Repository navigation
Chore/monorepo - #18
Merged
Merged
Conversation
Move the Next.js site to apps/web with git mv so history is preserved, and turn the repo root into the monorepo root for the ACM platform. - pnpm-workspace.yaml with apps/* and packages/*; the previous file only held an invalid allowBuilds placeholder - root package.json with dev/build/lint/typecheck/test/format delegating to turbo - pin Node 24 (.nvmrc + engines) and pnpm 12.4.2 (packageManager) - turbo.json: build dependsOn ^build, dev non-cached and persistent - packages/config with the shared tsconfig base and Biome config; - .gitignore paths unanchored so they match nested workspaces
Move the Next.js site to apps/web with git mv so the history follows it, and turn the repo root into the monorepo root for the ACM platform. - pnpm-workspace.yaml listing apps/* and packages/*; the previous file was unusable, it only held an allowBuilds placeholder string and no packages key - root package.json with dev/build/lint/typecheck/test/format on turbo - pin Node 24 (.nvmrc + engines) and pnpm 12.4.2 (packageManager) - turbo.json: build dependsOn ^build, dev non-cached and persistent - packages/config holds the shared tsconfig base and Biome config; the repo stays on Biome instead of moving to ESLint + Prettier - nested Biome configs need root: false and resolve the shared config through the @plataforma/config specifier, a relative path does not resolve - unanchor the .gitignore paths so they match nested workspaces, and ignore .idea/ No Vercel change here. The Root Directory has to move to apps/web before this lands on main.
apps/api is a hand written NestJS 12 app rather than a nest new scaffold,
which would have pulled in ESLint, Prettier and Jest that this repo does
not use.
- GET /health runs select 1 and reports both the api and the database:
200 {status: ok, db: up}, or 503 {status: degraded, db: down}
- API_PORT configures the port, 4000 by default
- CORS_ORIGIN is a comma separated list, parsed by parseCorsOrigins, which
falls back to the local web app so a fresh clone works with no env file
- src/db/client.ts exports the pg pool; Drizzle goes on top of it next
- useImportType is off for this package: import type would erase the
metadata Nest reads to resolve constructor dependencies
The endpoint answers 503 until the database lands in the next commit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docker-compose.yml runs Postgres 18 with a named volume and a pg_isready
healthcheck, and apps/api talks to it through Drizzle.
- src/config/env.ts loads the root .env with Node's own loadEnvFile and
defaults to the compose credentials, so a fresh clone needs no .env
- schema.ts holds a single placeholder health_check table; the first PR
with a real table should drop it
- 0000_keen_white_queen.sql is the baseline migration, and re-running
db:generate produces nothing, which is what CI will assert
- db:generate, db:migrate, db:studio, db:seed and db:reset, on the api
package and mirrored at the root
- db:seed builds first: node cannot run src/db/seed.ts directly, type
stripping treats it as ESM and demands file extensions
- Postgres 18 moved its volume to /var/lib/postgresql
- drizzle/ is excluded from Biome so the formatter does not fight
drizzle-kit output
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rename the workspace packages and the local dev database from plataforma
to acmfeup, which matches the organisation name and reads more naturally
for contributors.
- @plataforma/{web,api,config} become @acmfeup/{web,api,config}, and the
root package and the db:* filters follow
- the Docker container, database, user and password become acmfeup, with
.env.example and the DATABASE_URL default in env.ts updated to match
The database credentials changed, so an existing local volume still holds
the old user: run pnpm db:reset once after pulling.
/status calls the API's /health from the browser and shows whether the
API and the database are reachable. It is the end to end check for local
setup and the reference for how the web app calls the API.
- the request runs client side on purpose so it also exercises CORS
- next.config.ts loads the root .env, since Next only reads its own
folder and NEXT_PUBLIC_API_URL has to be there when it gets inlined
- turbo hashes .env and NEXT_PUBLIC_API_URL so a changed API URL cannot
replay a stale build, and dev passes the runtime vars through
- noindex, it is a diagnostic page
- lefthook runs biome check --write on staged files before each commit;
its own postinstall installs the hook on pnpm install and skips CI
- vitest in web and api with one example test each; tsconfig.build.json
keeps test files out of the api's dist, which vitest 5 no longer skips
- pr.yml runs lint, typecheck, test and build as a matrix with pnpm and
turbo caches, and cancels superseded runs on the same PR
- the migrations job applies every migration to an empty Postgres, then
fails if db:generate leaves any file behind; it checks git status
rather than git diff, since a new migration is an untracked file
- gitleaks runs through the official action and needs the
GITLEAKS_LICENSE org secret, as acmfeup is an organisation
- issue forms for features and bugs, a PR template and CODEOWNERS
- linter.yml is gone, the lint job replaces it
Co-Authored-By: Claude
- README replaces the create-next-app template: what the repo is, the four commands to get running, and the everyday scripts - setup uses docker compose up -d --wait: without --wait, db:migrate raced Postgres' first start and failed 2 out of 3 times, with no error printed - CONTRIBUTING covers issue to merge, the Definition of Ready, the seven day rule for draft PRs, and the migration rules - AGENTS.md sets the conventions for every coding agent, starting with the rule that whoever opens a PR must be able to explain it in review; CLAUDE.md only imports it, since Claude Code does not read AGENTS.md Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The current diff introduces build/CI blockers (invalid GitHub Action versions, missing React type imports, and invalid/nested HTML structure in Next layout/404 link button).
Review effort: Lite
Findings: None
What changed in this PR
Converts the repository into a pnpm + Turborepo monorepo containing the ACM FEUP Next.js website (apps/web) and a new NestJS + Drizzle + Postgres API (apps/api), with shared lint/typecheck config, local Docker Postgres, and CI/automation for multi-package development.
Changes:
- Added monorepo tooling (pnpm workspaces, Turborepo tasks, shared Biome/tsconfig in
packages/config) and standardized root scripts. - Introduced a NestJS API with a
/healthendpoint, Drizzle schema + initial migration, and root.envloading defaults. - Added web app structure and UI (status page, components, assets), plus CI workflow and repo contribution/agent docs.
| File | Description |
|---|---|
| turbo.json | Turborepo pipeline configuration (tasks, outputs, env passthrough). |
| README.md | Monorepo-focused setup and command documentation. |
| pnpm-workspace.yaml | Workspace package discovery + allowBuilds configuration. |
| packages/config/tsconfig.base.json | Shared TypeScript base config for all packages. |
| packages/config/package.json | Shared config package metadata. |
| packages/config/biome.json | Shared Biome configuration. |
| package.json | Root scripts + pinned package manager and engines for monorepo orchestration. |
| lefthook.yml | Pre-commit Biome formatting/linting for staged files. |
| docker-compose.yml | Local Postgres service for API/database development. |
| CONTRIBUTING.md | Contribution workflow + migration and secret-handling guidelines. |
| CLAUDE.md | Agent instruction pointer to @AGENTS.md. |
| biome.json | Root Biome config now extends shared config. |
| apps/web/tsconfig.json | Web tsconfig now extends shared base. |
| apps/web/src/lib/utils.ts | Adds cn utility for className composition. |
| apps/web/src/lib/utils.test.ts | Adds Vitest coverage for cn. |
| apps/web/src/components/ui/card.tsx | Adds shared Card UI primitives. |
| apps/web/src/components/ui/button.tsx | Adds shared Button component (variants + asChild). |
| apps/web/src/components/DepartmentCard.tsx | Adds department card component used on the home page. |
| apps/web/src/components/Countdown.tsx | Adds countdown/timer component rendered on the home page. |
| apps/web/src/app/status/status-check.tsx | Client-side API/DB status check UI and fetch logic. |
| apps/web/src/app/status/page.tsx | /status page shell and metadata. |
| apps/web/src/app/sitemap.ts | Sitemap route for the site. |
| apps/web/src/app/page.tsx | New/updated home page content and layout. |
| apps/web/src/app/not-found.tsx | Custom 404 page. |
| apps/web/src/app/manifest.json | PWA manifest metadata. |
| apps/web/src/app/layout.tsx | Root layout with fonts + analytics/speed insights + head tags. |
| apps/web/src/app/icon1.png | App icon asset. |
| apps/web/src/app/icon0.svg | SVG icon asset with light/dark variants. |
| apps/web/src/app/globals.css | Tailwind v4 + design tokens and base layer styles. |
| apps/web/src/app/favicon.ico | Favicon asset. |
| apps/web/src/app/apple-icon.png | Apple touch icon asset. |
| apps/web/public/window.svg | Public asset (window icon). |
| apps/web/public/web-app-manifest-192x192.png | Public PWA icon asset (192). |
| apps/web/public/vercel.svg | Public asset (Vercel logo). |
| apps/web/public/robots.txt | Robots rules + sitemap link. |
| apps/web/public/next.svg | Public asset (Next.js logo). |
| apps/web/public/globe.svg | Public asset (globe icon). |
| apps/web/public/file.svg | Public asset (file icon). |
| apps/web/public/acm-square-white.png | Public asset (square logo). |
| apps/web/public/acm_logo.png | Public asset (logo). |
| apps/web/postcss.config.mjs | PostCSS config for Tailwind in apps/web. |
| apps/web/package.json | Web package scripts + dependencies for Next/Tailwind/Vitest. |
| apps/web/next.config.ts | Loads repo-root .env and Next config adjustments for monorepo. |
| apps/web/components.json | shadcn/ui component config for the web app. |
| apps/web/biome.json | Web Biome config extending shared config + Next/React domains. |
| apps/api/tsconfig.json | API tsconfig extending shared base with Nest decorator metadata enabled. |
| apps/api/tsconfig.build.json | Build tsconfig excluding test files. |
| apps/api/src/main.ts | NestJS bootstrap, env/CORS wiring, and server listen. |
| apps/api/src/health/health.service.ts | DB health check implementation (select 1). |
| apps/api/src/health/health.controller.ts | /health endpoint returning ok/degraded payloads. |
| apps/api/src/db/seed.ts | Seed script placeholder and pool teardown. |
| apps/api/src/db/schema.ts | Drizzle schema (placeholder health_check table). |
| apps/api/src/db/client.ts | Postgres pool + Drizzle client export. |
| apps/api/src/config/env.ts | Root .env loading and defaults for API config. |
| apps/api/src/config/cors.ts | CORS origin parsing helper. |
| apps/api/src/config/cors.test.ts | Vitest coverage for CORS parsing. |
| apps/api/src/app.module.ts | Nest module wiring for health controller/service. |
| apps/api/package.json | API package scripts + Nest/Drizzle/pg dependencies. |
| apps/api/nest-cli.json | Nest CLI build config. |
| apps/api/drizzle/meta/0000_snapshot.json | Drizzle schema snapshot metadata for migration baseline. |
| apps/api/drizzle/meta/_journal.json | Drizzle migration journal metadata. |
| apps/api/drizzle/0000_keen_white_queen.sql | Initial SQL migration creating health_check. |
| apps/api/drizzle.config.ts | Drizzle-kit configuration using env-based DB URL. |
| apps/api/biome.json | API Biome config (including Nest DI import-type rule override). |
| AGENTS.md | Repository conventions for coding agents and repo workflows. |
| .nvmrc | Pins Node major version for local dev/CI. |
| .gitignore | Updates ignores for monorepo builds, env files, and editor tooling. |
| .github/workflows/pr.yml | CI pipeline for lint/typecheck/test/build + migrations + gitleaks. |
| .github/workflows/linter.yml | Removes legacy linter workflow. |
| .github/pull_request_template.md | Adds PR template with checklist and structure. |
| .github/ISSUE_TEMPLATE/feature.yml | Feature issue template. |
| .github/ISSUE_TEMPLATE/bug.yml | Bug report issue template. |
| .github/CODEOWNERS | Adds code ownership requirements. |
| .env.example | Documents supported env vars and defaults template. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Bebaz0
marked this pull request as draft
September 19, 2026 01:19
- api: handle idle-client errors on the pg pool so a Postgres restart
no longer crashes the process
- api: set connectionTimeoutMillis to 5s so /health reports the db as
down instead of hanging on an unreachable host
- api: use || for env defaults so blank values in .env fall back to
the docker-compose defaults
- web: treat non-503 error responses from /health as a failed check
instead of reporting the database as unreachable
Bebaz0
marked this pull request as ready for review
September 19, 2026 17:00
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes
Turns this repo into the monorepo for the ACM FEUP site and the ACM Platform API. The site moves to
apps/webwith its git history preserved, a NestJS API joins it inapps/api, and local development and CI are set up so several people can start working. No features and no deploy: this is structure, tooling and docs only.One commit per stage, meant to be reviewed commit by commit:
2daa7d6,a3f7020packages/config, Node 24 and pnpm 12 pinned2d6e503GET /healththat runsselect 11c43421132e194@plataformato@acmfeupc02021b/statuspage on the site, calling the API from the browserbd5fdd6.github/workflows/pr.ymlacc9009Decisions worth knowing before reviewing:
packages/config. No ESLint or Prettier..envat the repo root, optional: every value has a local default, so a fresh clone runs without one.linter.ymlis gone.pr.ymlruns lint, typecheck, test and build, plus amigrationsjob (every migration applied to an empty Postgres, and a check thatdb:generateproduces nothing) and agitleakssecret scan.How to test
Then open http://localhost:3000/status: both API and Database should read Connected.
Verified locally:
pnpm lint,pnpm typecheck,pnpm testandpnpm buildpass at the root, also on a clean copy withCI=trueand--frozen-lockfile.migrationsjob logic against a throwaway Postgres: applies from scratch, passes with no drift, fails whenschema.tschanges without a migration.Before merging
apps/web. Without it, the first production deploy frommainbreaks acmfeup.eu.GITLEAKS_LICENSEadded as an org secret (acmfeup is an organisation, so the action needs its free license). Thegitleaksjob stays red until then.Expected, not bugs
noindex.health_checkis a placeholder table, so the migration pipeline has something to apply. The first PR with a real table should drop it.After merging
Anyone with an existing checkout should delete the old root
node_modulesand.nextand runpnpm installagain.Checklist
parseCorsOrigins,cn)