Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/sync-md-to-supabase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Sync Markdown to Supabase

on:
push:
branches:
- main
workflow_dispatch:

jobs:
sync:
runs-on: ubuntu-latest
env:
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Sync markdown content
run: npm run sync:supabase
env:
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_SERVICE_KEY: ${{ secrets.SUPABASE_SERVICE_KEY }}
SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
22 changes: 22 additions & 0 deletions .github/workflows/validate-md.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Validate Markdown Frontmatter

on:
push:
branches:
- main
pull_request:

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Validate frontmatter
run: npm run validate:frontmatter
167 changes: 90 additions & 77 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,114 +1,127 @@
# FACODI — Faculdade Comunitária Digital

**FACODI** é uma plataforma EAD gratuita e open-source inspirada nos planos curriculares da Universidade do Algarve (UALG).
Nosso objetivo é **democratizar o acesso ao ensino superior** por meio de trilhas de estudo organizadas em cursos, unidades curriculares e playlists do YouTube.

🚀 Projeto mantido pela [Monynha Softwares](https://monynha.com).
FACODI é um portal de ensino superior aberto mantido pela comunidade. Todo o conteúdo editorial é versionado em Markdown e publicado como um site estático em [Hugo](https://gohugo.io) utilizando o tema **Doks**. Uma cópia normalizada das informações vive no banco de dados **Supabase**, que é utilizado para renderizar dados dinâmicos nas páginas de cursos, UCs e tópicos.

---

## ✨ Funcionalidades
## ✨ Principais recursos

- 📚 Catálogo de cursos e currículos completos
- 🎥 Aulas organizadas em **playlists do YouTube**
- 📝 Conteúdo textual em **Markdown versionado**
- 🔑 Autenticação via [Supabase Auth](https://supabase.com)
- 📊 Acompanhamento de progresso por vídeo
- 🌍 Multi-idioma: PT / EN / ES / FR
- 📚 Catálogo de cursos com versões de plano curricular.
- 🧭 Navegação Curso → UC → Tópico com conteúdo em Markdown.
- 🎥 Playlists do YouTube associadas a cada UC/tópico (carregadas do Supabase).
- 🗃️ Sincronização automatizada dos arquivos `.md` para o banco Postgres.
- 🌍 Estrutura preparada para internacionalização (PT padrão, EN fallback).

---

<!-- ## 🏗️ Arquitetura
## ⚙️ Como rodar localmente

- **Frontend**: [Next.js 14](https://nextjs.org) (App Router)
- **Banco de Dados**: [PostgreSQL + Supabase](https://supabase.com)
- **Docs**: Arquivos `.md` sincronizados com banco
- **Infra**: Deploy automatizado via [Coolify](https://coolify.io) em servidor Hetzner
- **Design**: UI baseada em [shadcn/ui](https://ui.shadcn.com) + Tailwind + tokens Monynha
> Pré-requisitos: Node.js 20+, [Hugo Extended](https://gohugo.io/installation/), Supabase CLI (opcional para executar o banco local).

--- -->
```bash
# Instalar dependências
npm install

## 📂 Estrutura do Repositório
# Executar site em modo de desenvolvimento
npm run dev

```bash
facodi-docs/
├─ README.md
├─ .github/
│ └─ workflows/
│ ├─ validate-md.yml
│ └─ sync-md-to-supabase.yml
├─ config/
│ ├─ _default/
├─ scripts/
├─ package.json
├─ package-lock.json
├─ content/
│ ├─ _index.md
│ └─ courses/
│ └─ LESTI/
│ └─ 2024-2025/
│ ├─ index.md
│ └─ uc/
│ ├─ LESTI-ALG1/
│ │ ├─ index.md
│ │ └─ estruturas-de-dados.md
│ └─ LESTI-BD1/
│ └─ index.md
├─ static/ (opcional: imagens anexas ao conteúdo)
│ └─ courses/
│ └─ ...
└─ schemas/ (opcional: documentação de esquema e seeds)
├─ README.md
├─ mapping.md
└─ examples/
└─ frontmatter-samples.md
````
# Gerar build estática
npm run build
```

---
Para que os dados dinâmicos apareçam, exporte as variáveis do Supabase antes de iniciar o servidor:

## ⚙️ Como rodar localmente
```bash
export SUPABASE_URL="https://<project>.supabase.co"
export SUPABASE_ANON_KEY="<anon-key>"
```

Para executar as rotinas de sincronização ou validar o conteúdo Markdown:

```bash
# Clonar o repositório
git clone https://github.com/Monynha-Softwares/facodi.pt.git
cd facodi.pt
# Validação de frontmatter
npm run validate:frontmatter

# Instalar dependências
pnpm install
# Sincronizar Markdown → Supabase (usa SUPABASE_SERVICE_KEY)
npm run sync:supabase
```

---

# Iniciar Supabase local
pnpm supabase start
## 📂 Estrutura do projeto

# Rodar o frontend
pnpm dev --filter=web
```
facodi.pt/
├─ content/
│ └─ courses/
│ └─ <curso>/<plano>/
│ ├─ index.md # Metadados do curso
│ └─ uc/<uc>/
│ ├─ index.md # Metadados da UC
│ └─ <topico>.md # Metadados do tópico
├─ layouts/
│ ├─ _default/baseof.html # Layout base com integração Supabase
│ ├─ home.html # Página inicial (lista de cursos)
│ ├─ course/single.html # Template de curso
│ ├─ uc/single.html # Template de UC
│ └─ topic/single.html # Template de tópico
├─ static/js/
│ ├─ supabaseClient.js # Instância do cliente Supabase (browser)
│ └─ loaders.js # Funções para carregar cursos/UCs/tópicos
├─ supabase/
│ ├─ migrations/ # Schemas + RLS
│ └─ seeds/ # Dados de exemplo (LESTI)
└─ .github/workflows/
├─ validate-md.yml # Valida frontmatter
└─ sync-md-to-supabase.yml # Publica conteúdo no banco
```

---

## 🤝 Contribuindo
## 🗄️ Banco de dados Supabase

Os migrations definem os schemas `catalog`, `subjects` e `mapping`, contendo as tabelas:

FACODI é open-source! Você pode contribuir de várias formas:
- `catalog.course`, `catalog.course_content`
- `catalog.uc`, `catalog.uc_content`, `catalog.uc_learning_outcome`
- `subjects.topic`, `subjects.topic_content`, `subjects.topic_tag`
- `mapping.uc_topic`, `mapping.uc_playlist`, `mapping.topic_playlist`

1. Fork o projeto e abra um Pull Request
2. Relate bugs ou sugira features em [Issues](../../issues)
3. Traduza conteúdos (PT → EN/ES/FR)
4. Ajude a revisar planos curriculares e trilhas de estudo
Todas as tabelas possuem RLS habilitado com política de leitura pública (`role anon`) e escrita restrita ao `service_role`.

Consulte nosso guia em [`CONTRIBUTING.md`](./CONTRIBUTING.md).
### Executando localmente

```bash
# Inicializar Supabase local
supabase start

# Aplicar migrations e seeds
supabase db reset
```

Após subir o banco, configure as variáveis `SUPABASE_URL`, `SUPABASE_ANON_KEY` e `SUPABASE_SERVICE_KEY` no seu ambiente e/ou nos segredos do GitHub.

---

## 👩‍💻 Autores & Créditos
## 🧪 CI/CD

Dois workflows acompanham o projeto:

* [Marcelo Santos](https://github.com/marcelosantos) — fundador do projeto
* Comunidade Monynha Softwares
* Base acadêmica: planos curriculares da [UALG](https://www.ualg.pt)
1. **`validate-md.yml`** — Executa `npm run validate:frontmatter` em pushes e pull requests.
2. **`sync-md-to-supabase.yml`** — Publica o conteúdo Markdown no banco utilizando `SUPABASE_SERVICE_KEY`. Pode ser disparado manualmente (`workflow_dispatch`) ou em pushes para `main`.

---

## 📜 Licença
## 🤝 Contribuição

1. Faça um fork e crie uma branch com sua feature.
2. Garanta que `npm run validate:frontmatter` e `npm run build` estão passando.
3. Abra um Pull Request descrevendo as mudanças.

Este projeto é distribuído sob a licença **MIT**.
Veja o arquivo [`LICENSE`](./LICENSE) para mais detalhes.
Consulte também [`CONTRIBUTING.md`](./CONTRIBUTING.md) para orientações gerais.

---

## 📜 Licença

Distribuído sob a licença [MIT](./LICENSE).
25 changes: 25 additions & 0 deletions config/_default/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
baseURL = "https://facodi.pt/"
title = "FACODI — Faculdade Comunitária Digital"
languageCode = "pt-PT"
defaultContentLanguage = "pt"
defaultContentLanguageInSubdir = false

[languages]
[languages.pt]
languageName = "Português"
contentDir = "content"
weight = 1
[languages.pt.params]
languageISO = "PT"
languageTag = "pt-PT"
[languages.en]
languageName = "English"
contentDir = "content/en"
weight = 2
[languages.en.params]
languageISO = "EN"
languageTag = "en-US"

[security]
[security.funcs]
getenv = ['^HUGO_', '^CI$', '^SUPABASE_']
10 changes: 5 additions & 5 deletions config/_default/hugo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
title = "Monynha Docs"
baseurl = "https://docs.monynha.com/"
title = "FACODI — Faculdade Comunitária Digital"
baseurl = "https://facodi.pt/"
disableAliases = true
disableHugoGeneratorInject = true
# disableKinds = ["taxonomy", "term"]
enableEmoji = true
enableGitInfo = false
enableRobotsTXT = true
languageCode = "en-US"
languageCode = "pt-PT"
rssLimit = 10
summarylength = 20 # 70 (default)

# Multilingual
defaultContentLanguage = "en"
defaultContentLanguage = "pt"
disableLanguages = ["de", "nl"]
defaultContentLanguageInSubdir = false

copyRight = "Copyright (c) 2020-2024 Thulite"
copyRight = "Copyright (c) 2025 FACODI"

[build.buildStats]
enable = true
Expand Down
37 changes: 11 additions & 26 deletions config/_default/languages.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
[pt]
languageName = "Português"
contentDir = "content"
weight = 10
[pt.params]
languageISO = "PT"
languageTag = "pt-PT"
footer = 'Conteúdo distribuído pela comunidade FACODI.'

[en]
languageName = "English"
contentDir = "content/en"
weight = 10
weight = 20
[en.params]
languageISO = "EN"
languageTag = "en-US"
footer = 'Brought to you by <a class="text-muted" href="https://thulite.io/">Thulite</a>'
alertText = '<a class="alert-link stretched-link fw-normal" href="/blog/example-post/">Doks version 1.0 just shipped!</a>'

[de]
languageName = "German"
contentDir = "content/de"
weight = 15
[de.params]
languageISO = "DE"
languageTag = "de-DE"
footer = 'Gebaut mit <a class="text-muted" href="https://thulite.io/">Thulite</a>'
alertText = 'Neue Version ist da! <a class="alert-link stretched-link" href="https://getdoks.org/blog/doks-v0.5/">Doks v0.5</a>'

[nl]
languageName = "Nederlands"
contentDir = "content/nl"
weight = 20
[nl.params]
languageISO = "NL"
languageTag = "nl-NL"
titleAddition = "Modern documentatie-thema"
description = "Doks is een Hugo-thema waarmee je moderne documentatie-websites kunt bouwen die veilig, snel en klaar voor SEO zijn — standaard."
titleHome = "Doks thema"
footer = 'Mogelijk gemaakt door <a href="https://www.netlify.com/">Netlify</a>, <a href="https://gohugo.io/">Hugo</a>, en <a href="https://getdoks.org/">Doks</a>'
alertText = 'Introductie van het Doks-kinderthema, verschillende DX + UX-updates en meer! <a class="alert-link stretched-link" href="https://getdoks.org/blog/doks-v0.2/">Bekijk Doks v0.2</a>'
footer = 'Content provided by the FACODI community.'
Loading