Repository navigation
Feature/projeto web - #9
Merged
Merged
Conversation
Add section 6 to the HLD covering local, CI, staging and production environments, and the delivery flow. Renumber decisions to section 7 and record the new decisions, risk and open questions. Update the LLD so deadlines and token lifetimes are read from environment variables, and list the new variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep the repository root free for the monorepo that will be created, with the brief, HLD and LLD grouped in one place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Give future agent sessions the document hierarchy, the planned architecture and the working rules (Docker networking, definition of done, Git conventions, scope limits and library documentation lookup). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use the agent-neutral file name so the same guidance serves tools other than Claude Code, and trim it to the current working rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scaffold apps/web with create-next-app, following the structure in the LLD. Development and production use separate Dockerfiles: the dev container only stays up so commands run through docker compose exec, while the production image runs the standalone server for Cloud Run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share the chrome-devtools and playwright servers so everyone working on the repo gets the same browser tooling without approving them by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installing inside the dev container created a .pnpm-store folder in apps/web, because pnpm places the store next to the bind-mounted code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Document how to start and stop the project and how to run commands in the container, so nobody runs pnpm or node directly on the host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scaffold apps/api with the Nest CLI, following the structure in the LLD, with separate development and production Dockerfiles like the web app. The dev image includes procps because Nest's watch mode needs ps to stop the previous process on each reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drop the node_modules volumes so dependencies land in the project folder, where the editor can read them, and are installed when the container starts instead of by hand. Also add the api service to the dev compose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Record the decisions from the planning session so the Linear tickets have a single source of truth: the LLD now covers users and sessions, the glossary fixes the terms Usuário and Sessão, and AGENTS.md describes how specs and tickets are managed in Linear. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGENTS.md now sends specs and tickets to Linear, so the server has to be available to anyone working in the repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The LLD and the API AGENTS.md were describing the same rules in two places and had to change together. Each piece of information now has a single owner: what the system does lives in docs/, how the code is written lives in the AGENTS.md of each project, and the root AGENTS.md records that rule. - apps/api/AGENTS.md: commands, layers, what the service layer may import, domain errors translated by an exception filter, Nest file naming, test levels by suffix, and the config module. - apps/web/AGENTS.md: Server Components first, data access, and the cache trade-offs under Cache Components. - docs/lld.md: keeps the folder tree and the library choices, and gains the config module and the PORT variable. - docs/plans/01-auth.md: removed. The plan lives in Linear (LUI-133). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Versions the skills used to plan features (grilling, domain modeling, research, spec and tickets), installed from mattpocock/skills, together with the lock file that pins their hashes, so every clone plans with the same workflow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The authentication screens were drawn in Figma (LUI-134) and needed a success banner, a narrow banner layout and extra auth-card content that the design system did not describe yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The components in Figma gained hover, focus and disabled variants, and the design system did not say how a filled control looks when disabled or how the focus outline is represented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hover and disabled controls were unreadable on the Figma page background and the disabled button vanished in the dark theme. A dedicated fill-disabled token replaces surface, the field hover now changes the border, and the file pages and their showcase rules are documented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pointer was lost when the placeholder line was removed, so the design system no longer said where the Figma file lives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nticacao-no-figma docs: authentication screens in Figma (LUI-134)
The auth slices need a database and an inbox from the first run. The api container now prepares its own .env, RS256 keys and migrations on start, so a fresh clone needs no manual step, and healthchecks let 'up --wait' block until that is done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
Every auth slice relies on these: routes under /v1, one filter that shapes all errors with a stable code, env vars validated at boot, an e-mail interface with an SMTP driver, and e2e/integration suites that run against a real test database and Mailpit. The example controller is gone, so the unit suite must pass empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…body Keeps each fact in its owner: environment in the root guide, code practices and commands in the API guide, error contract, env vars and the Prisma 7 pin in the LLD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
A third-party SDK error carrying statusCode 404 was answered as a client error and never logged. The filter now takes the status only from HttpException and body-parser errors, keeps deliberate 5xx statuses instead of flattening them to 500, and drops the connection when the response has already started. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
Subject configs re-read raw process.env, so conversion and defaults lived outside the schema and a value changed after boot skipped validation. The PEM regex also accepted unparsable keys and refused valid PKCS#1 ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
nodemailer defaults keep a send hanging for minutes on a stuck server, so the timeouts are now explicit and configurable. The Mailpit helper returned as soon as any message existed, which would hand a resend test the first e-mail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
pg_isready over the unix socket also passes on the temporary init server, letting the api start migrating too early. The production image cannot apply migrations; that is out of scope here, so the open decision is written down in the HLD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…ne place The three Vitest configs, the env stub cleanup and the problem+json assertions were copied across files, and the env schema ran through two separate mechanisms. Each now has a single owner, so the next feature copies one pattern instead of four. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
With the pg adapter, $connect() opens no connection, so the API booted against a dead database and only failed on the first request. The env setup script also replaced a key the developer had put in .env when the other half of the pair was missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
The test database URL is now derived once per run and handed to the test files, so a development database whose name already ends in _test can no longer be truncated. The env is validated once per set of values, SMTP connections are pooled, tests read mail from the server SMTP_URL points to, and the scaffold leftovers are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…ecks A database that accepts the connection and never answers held the boot forever, because pg waits without a limit by default. The env schema now also refuses a JWT public key that is not the pair of the private one and a MAIL_FROM without an address, which used to fail only at runtime. The test base hands the Mailpit address to the test files once, so a test that swaps SMTP_URL keeps reading from the right server, and a test app that fails to boot is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…he SMTP idle wait A HttpException carrying a 2xx/3xx status went out as a problem document with a success status. The SMTP socket timeout doubled as the pool's idle limit, so pooled connections were dropped before being reused; the inactivity wait now has its own, longer setting. Also documents how to repair the environment when the API container exits during setup, and the Prisma CLI config as the second place that reads the environment directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
The filter took any thrown object with expose, a string type and a 4xx statusCode as an Express body-reader error, so a third-party error with that shape leaked its status instead of becoming a 500. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…ente-banco-email-erros feat: foundation for auth — environment, database, e-mail and error format (LUI-135)
…rowser tests (LUI-136) The auth screens of feature 01 need a shared base before the first slice (LUI-137): the design-system tokens in Tailwind, the primitives and the auth card from the approved Figma screens, a server-only API client that returns errors typed by `code`, and a Playwright service in the dev Compose. The default Tailwind colour, text, radius and shadow scales are wiped so only token classes generate CSS. A dev-only showcase under /vitrine gives the components somewhere to be validated and tested until the screens exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…and give Chromium shared memory Review findings on the web base: a caller could override the `aria-busy` derived from `loading`, a disabled text link still looked and hovered like an enabled one, and Chromium ran on Docker's 64 MB /dev/shm with a parallel suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…omponentes-auth feat: web base for auth — design tokens, components, API client and browser tests (LUI-136)
…eens (LUI-137) A visitor can now create a User with e-mail and password, receive the verification link, open it and land on the sign-in screen with the success notice, or ask for another link when the first one is lost, expired or used. Sign-up never reveals whether an e-mail already has a User: the answer is always 201 and only the e-mail sent differs. While an e-mail is unverified the last sign-up wins (password and terms acceptance), decided by a conditional update so a verification that lands in between is not overwritten. A verification token is unique per User and type, so concurrent resends cannot leave two valid links. The users module owns the users table and the auth module reaches it only through its public service. WEB_ORIGIN and EMAIL_VERIFICATION_TTL_SECONDS are new, and the setup script now adds to an existing .env whatever .env.example gained, so the API keeps booting on machines that already have one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…en verification fails Review findings on sign-up and verification. The "confira seu e-mail" screen received the address in the query string, which left it in browser history and access logs and let anyone craft a link with arbitrary text on the screen. The address now travels in a one-hour HttpOnly cookie scoped to that screen, and the resend reads it from there instead of from a form field. Verification spent the token and then marked the User in a second statement; a failure in between left the link dead with the User still unverified. The token is now released when marking fails, so the same link works again. The local web container sets COOKIE_SECURE=false, because it runs over HTTP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…rificacao feat: sign-up and e-mail verification, from the API routes to the screens (LUI-137)
A verified User can now sign in with e-mail and password, land on a provisional page that shows their e-mail and sign out. Opening a protected page without a Session leads to the sign-in screen and back to the requested page after login; opening an auth screen with a Session leads to the product. Login opens a Session: an RS256 access token and an opaque refresh token stored only as a hash, grouped by a session id. A wrong password and an unknown e-mail get the same answer, and the password is checked even without a User so the response time does not tell them apart. Logout deletes the Session's tokens and answers 204 whatever the token is. GET /me belongs to the users module, behind a guard that checks only the signature. On the web the tokens live in HttpOnly cookies. The Proxy is an optimistic filter that reads the token expiry without checking the signature, and every route outside its two lists is protected. The data access layer asks the API on each protected page; a Session the API refuses is cleared by a route that checks it again first, because rendering a page cannot delete cookies. The return destination accepts internal paths only. Session renewal is not here yet, so an expired access token leads to the sign-in screen. ACCESS_TOKEN_TTL_SECONDS and REFRESH_TOKEN_TTL_SECONDS are new. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
… of any size Review findings on the session routes: the guard compared the scheme case-sensitively, although RFC 7235 makes it case-insensitive, and accepted a header with anything after the token. The logout route refused a token longer than 512 characters with validation_error, while the contract says 204 even for an invalid token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
feat: sign-in and sign-out, from the API routes to the screens (LUI-138)
…xy (LUI-139) A User now stays signed in after the 15-minute access token expires, without noticing, for as long as the Session is in use. Several tabs can renew at the same time. When the Session is really over, the sign-in screen says so. POST /auth/refresh trades the refresh token for a new pair in the same Session and marks the old token as rotated. A rotated token is still accepted for REFRESH_TOKEN_REUSE_GRACE_SECONDS (10 by default), so parallel requests do not knock each other out; each use opens another branch of the Session. After the window, reuse means possible theft and ends every Session of the User, even if the rotated token has already expired. Rotation, logout and that mass revocation queue up per User in the database, so a refresh that races a logout cannot leave a new token in a Session that was just deleted. On the web the Proxy renews before the route renders and passes the new tokens along in the request. If the API refuses the refresh token, it clears the cookies and leads to the sign-in screen with "Sua sessão expirou"; if the API fails, the Session is kept. A Server Action is never redirected by the Proxy, because the browser would replay it on the sign-in screen and show an error. That is what lets sign-out work with an expired access token, which used to leave the Session alive on the server. /sessao-encerrada also tries to renew before it clears anything. The two logout tests left as todo in LUI-138 are now real: the refresh route makes the end of a Session observable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…reuse Review findings on the refresh route. Reuse was detected in one transaction and the Sessions were deleted in another, so a refresh on another branch of the User could take the lock in between and still get a new pair. The rotation now deletes the User's tokens itself, under the same lock. The grace window is closed at its end: a token rotated exactly at the limit is refused, so a window of zero really turns the tolerance off. A new test fires refresh and logout together, through the routes, and checks that no token of the Session renews afterwards. It fails without the lock. apps/api/AGENTS.md said the service owns transactions, while only repositories have the database client. The rule now says the repository guarantees the atomicity of each command and returns a typed outcome. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…-renova feat: a Session that renews itself, from the refresh route to the Proxy (LUI-139)
A User who forgot the password asks for a link by e-mail, sets a new password and lands on the sign-in screen with the "Senha redefinida" notice. Neither the answer nor the screens say whether the e-mail has a User. POST /auth/forgot-password always answers 204 and only sends the link when the e-mail has a User, verified or not. The token lasts PASSWORD_RESET_TTL_SECONDS (1 hour by default), is stored as a hash and is replaced by the next request. POST /auth/reset-password spends it, ends every Session of the User, changes the password, marks the e-mail as verified and sends "Sua senha foi alterada". It opens no Session. The Sessions end before the password changes: if the change then fails, the person only has to sign in again and the link is given back, instead of a new password living next to the old Sessions. The token is checked before the Argon2 hash runs, so a made-up token does not cost one. "Spend the token and give it back if what it authorises fails" now lives in EmailTokensService.redeem(), shared with e-mail verification. On the web, /esqueci-minha-senha and /redefinir-senha open with or without a Session, because the links in the e-mails and the invalid-link screen lead there. Only the API knows whether a token is valid, so an invalid link is found when the new password is sent. The reset form is rendered only after the token is read from the URL: as a hidden field streamed in later, it was left out of a fast submit and sent a good link to the invalid-link screen. After the reset the web clears the token cookies of the browser, so the sign-in screen opens instead of the Proxy leading back to the product. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
Review finding on the forgot-password route: an e-mail without a User returned at once, while an e-mail with one still wrote the token before answering, so the response time told the two apart despite the same 204. The route now answers right after looking the User up, which costs the same in both cases. The token and the e-mail follow without being awaited. A failure to write the token goes to the log, as a failure to send already did, and the person asks for another link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…e-senha feat: password recovery, from the reset routes to the screens (LUI-140)
…IP (LUI-141) Login, registration, verification resend and "forgot password" now count attempts per e-mail and per IP in PostgreSQL and answer rate_limited until the window closes, so guessing a password or flooding a mailbox stops being free. The web forwards the browser's IP with a shared secret, so one abuser does not lock everyone out behind the web server's address. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RgE8sJLFxENgwV47XrwDGP
…tativas-e-ip-real feat: attempt limits on the auth routes, keyed by the browser's real IP (LUI-141)
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
7 open findings
API does not configure CORS for WEB_ORIGIN · New forRoot returns incorrect asynchronous module type · New ClientIpGuard is not registered as a provider · New Verified email response timing enables enumeration · New Test database is not provisioned before migrations · New Password reset cookie type is incompatible · New README instructions bypass the required Docker workflow · New
What changed in this PR
Adds the initial web application, authentication flows, session handling, API authentication infrastructure, database schema, testing setup, and project skills.
Changes:
- Adds Next.js authentication UI, Server Actions, session cookies, proxy renewal, and Playwright tests.
- Adds NestJS users/auth modules, tokens, rate limiting, mail delivery, configuration, Prisma schema, and tests.
- Adds glossary, Docker setup, and agent skill documentation.
| File | Description |
|---|---|
| GLOSSARY.md | Updated as part of this pull request. |
| apps/web/tsconfig.json | Updated as part of this pull request. |
| apps/web/README.md | Updated as part of this pull request. |
| apps/web/public/.gitkeep | Updated as part of this pull request. |
| apps/web/pnpm-workspace.yaml | Updated as part of this pull request. |
| apps/web/playwright.config.ts | Updated as part of this pull request. |
| apps/web/package.json | Updated as part of this pull request. |
| apps/web/next.config.ts | Updated as part of this pull request. |
| apps/web/lib/session/tokens.ts | Updated as part of this pull request. |
| apps/web/lib/session/token-cookies.ts | Updated as part of this pull request. |
| apps/web/lib/session/return-path.ts | Updated as part of this pull request. |
| apps/web/lib/session/renewal.ts | Updated as part of this pull request. |
| apps/web/lib/session/paths.ts | Updated as part of this pull request. |
| apps/web/lib/session/login-path.ts | Updated as part of this pull request. |
| apps/web/lib/session/cookie-options.ts | Updated as part of this pull request. |
| apps/web/lib/session/access-token.ts | Updated as part of this pull request. |
| apps/web/lib/dal/user.ts | Updated as part of this pull request. |
| apps/web/lib/api/users.ts | Updated as part of this pull request. |
| apps/web/lib/api/types.ts | Updated as part of this pull request. |
| apps/web/lib/api/link-errors.ts | Updated as part of this pull request. |
| apps/web/lib/api/error-messages.ts | Updated as part of this pull request. |
| apps/web/lib/api/endpoint.ts | Updated as part of this pull request. |
| apps/web/lib/api/client-ip.ts | Updated as part of this pull request. |
| apps/web/lib/api/auth.ts | Updated as part of this pull request. |
| apps/web/eslint.config.mjs | Updated as part of this pull request. |
| apps/web/e2e/support/mailpit.ts | Updated as part of this pull request. |
| apps/web/e2e/support/env.ts | Updated as part of this pull request. |
| apps/web/e2e/support/account.ts | Updated as part of this pull request. |
| apps/web/e2e/smoke.spec.ts | Updated as part of this pull request. |
| apps/web/e2e/mailpit.spec.ts | Updated as part of this pull request. |
| apps/web/e2e/components.spec.ts | Updated as part of this pull request. |
| apps/web/e2e/api-client.spec.ts | Updated as part of this pull request. |
| apps/web/Dockerfile.dev | Updated as part of this pull request. |
| apps/web/Dockerfile | Updated as part of this pull request. |
| apps/web/components/ui/text-link.tsx | Updated as part of this pull request. |
| apps/web/components/ui/text-field.tsx | Updated as part of this pull request. |
| apps/web/components/ui/password-field.tsx | Updated as part of this pull request. |
| apps/web/components/ui/button-primary.tsx | Updated as part of this pull request. |
| apps/web/components/ui/button-icon.tsx | Updated as part of this pull request. |
| apps/web/components/ui/banner.tsx | Updated as part of this pull request. |
| apps/web/components/auth/auth-card.tsx | Updated as part of this pull request. |
| apps/web/app/vitrine/layout.tsx | Updated as part of this pull request. |
| apps/web/app/vitrine/auth-card/page.tsx | Updated as part of this pull request. |
| apps/web/app/vitrine/api/page.tsx | Updated as part of this pull request. |
| apps/web/app/termos/page.tsx | Updated as part of this pull request. |
| apps/web/app/sessao-encerrada/route.ts | Updated as part of this pull request. |
| apps/web/app/privacidade/page.tsx | Updated as part of this pull request. |
| apps/web/app/layout.tsx | Updated as part of this pull request. |
| apps/web/app/(drive)/page.tsx | Updated as part of this pull request. |
| apps/web/app/(drive)/actions.ts | Updated as part of this pull request. |
| apps/web/app/(auth)/verificar-email/route.ts | Updated as part of this pull request. |
| apps/web/app/(auth)/verificar-email/link-invalido/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/request-link-form.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/redefinir-senha/reset-password-form.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/redefinir-senha/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/redefinir-senha/link-invalido/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/pending-email.ts | Updated as part of this pull request. |
| apps/web/app/(auth)/paths.ts | Updated as part of this pull request. |
| apps/web/app/(auth)/form-state.ts | Updated as part of this pull request. |
| apps/web/app/(auth)/esqueci-minha-senha/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/esqueci-minha-senha/enviado/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/entrar/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/entrar/login-form.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/email-field.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/criar-conta/register-form.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/criar-conta/page.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/confira-seu-email/resend-verification.tsx | Updated as part of this pull request. |
| apps/web/app/(auth)/confira-seu-email/page.tsx | Updated as part of this pull request. |
| apps/web/.gitignore | Updated as part of this pull request. |
| apps/web/.dockerignore | Updated as part of this pull request. |
| apps/api/vitest.shared.ts | Updated as part of this pull request. |
| apps/api/vitest.config.ts | Updated as part of this pull request. |
| apps/api/vitest.config.int.ts | Updated as part of this pull request. |
| apps/api/vitest.config.e2e.ts | Updated as part of this pull request. |
| apps/api/tsconfig.json | Updated as part of this pull request. |
| apps/api/tsconfig.build.json | Updated as part of this pull request. |
| apps/api/test/support/test-env.ts | Updated as part of this pull request. |
| apps/api/test/support/setup.ts | Updated as part of this pull request. |
| apps/api/test/support/problem.ts | Updated as part of this pull request. |
| apps/api/test/support/global-setup.ts | Updated as part of this pull request. |
| apps/api/test/support/database.ts | Updated as part of this pull request. |
| apps/api/test/support/create-test-app.ts | Updated as part of this pull request. |
| apps/api/src/modules/users/users.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/users/users.module.ts | Updated as part of this pull request. |
| apps/api/src/modules/users/users.controller.ts | Updated as part of this pull request. |
| apps/api/src/modules/users/entities/user.entity.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/registration.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/password.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/password-recovery.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/opaque-token.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/format-duration.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/format-duration.spec.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/errors/invalid-token.error.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/errors/invalid-credentials.error.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/errors/email-not-verified.error.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/email-tokens.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/email-tokens.repository.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/email-token-type.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/verify-email.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/reset-password.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/resend-verification.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/register.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/refresh.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/new-password.decorator.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/logout.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/login.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/forgot-password.dto.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/email.decorator.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/dto/email-link-token.decorator.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/auth.module.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/auth.controller.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/auth-mailer.service.ts | Updated as part of this pull request. |
| apps/api/src/modules/auth/auth-attempts.service.ts | Updated as part of this pull request. |
| apps/api/src/main.ts | Updated as part of this pull request. |
| apps/api/src/infra/mail/smtp-mail-sender.ts | Updated as part of this pull request. |
| apps/api/src/infra/mail/mail.module.ts | Updated as part of this pull request. |
| apps/api/src/infra/mail/mail-sender.ts | Updated as part of this pull request. |
| apps/api/src/infra/database/prisma.service.ts | Updated as part of this pull request. |
| apps/api/src/infra/database/database.module.ts | Updated as part of this pull request. |
| apps/api/src/config/rate-limit.config.ts | Updated as part of this pull request. |
| apps/api/src/config/mail.config.ts | Updated as part of this pull request. |
| apps/api/src/config/env.ts | Updated as part of this pull request. |
| apps/api/src/config/database.config.ts | Updated as part of this pull request. |
| apps/api/src/config/config.module.ts | Updated as part of this pull request. |
| apps/api/src/config/auth.config.ts | Updated as part of this pull request. |
| apps/api/src/config/app.config.ts | Updated as part of this pull request. |
| apps/api/src/common/validation/input-validation.pipe.ts | Updated as part of this pull request. |
| apps/api/src/common/rate-limit/rate-limited.error.ts | Updated as part of this pull request. |
| apps/api/src/common/rate-limit/rate-limit.service.ts | Updated as part of this pull request. |
| apps/api/src/common/rate-limit/rate-limit.repository.ts | Updated as part of this pull request. |
| apps/api/src/common/rate-limit/rate-limit.module.ts | Updated as part of this pull request. |
| apps/api/src/common/errors/input-validation.error.ts | Updated as part of this pull request. |
| apps/api/src/common/errors/error-code.ts | Updated as part of this pull request. |
| apps/api/src/common/errors/domain-error.ts | Updated as part of this pull request. |
| apps/api/src/common/client-ip/client-ip.guard.ts | Updated as part of this pull request. |
| apps/api/src/common/client-ip/client-ip.guard.spec.ts | Updated as part of this pull request. |
| apps/api/src/common/client-ip/client-ip.decorator.ts | Updated as part of this pull request. |
| apps/api/src/common/client-ip/canonical-ip.ts | Updated as part of this pull request. |
| apps/api/src/common/client-ip/canonical-ip.spec.ts | Updated as part of this pull request. |
| apps/api/src/common/auth/unauthenticated.error.ts | Updated as part of this pull request. |
| apps/api/src/common/auth/current-user-id.decorator.ts | Updated as part of this pull request. |
| apps/api/src/common/auth/auth.guard.ts | Updated as part of this pull request. |
| apps/api/src/common/auth/access-tokens.service.ts | Updated as part of this pull request. |
| apps/api/src/common/auth/access-tokens.module.ts | Updated as part of this pull request. |
| apps/api/src/app.setup.ts | Updated as part of this pull request. |
| apps/api/src/app.module.ts | Updated as part of this pull request. |
| apps/api/scripts/setup-env.mjs | Updated as part of this pull request. |
| apps/api/README.md | Updated as part of this pull request. |
| apps/api/prisma/schema.prisma | Updated as part of this pull request. |
| apps/api/prisma/migrations/migration_lock.toml | Updated as part of this pull request. |
| apps/api/prisma/migrations/20261009100010_rate_limits/migration.sql | Updated as part of this pull request. |
| apps/api/prisma/migrations/20261009081006_refresh_tokens/migration.sql | Updated as part of this pull request. |
| apps/api/prisma/migrations/20261009075226_users_and_email_tokens/migration.sql | Updated as part of this pull request. |
| apps/api/prisma/migrations/20261009000000_enable_extensions/migration.sql | Updated as part of this pull request. |
| apps/api/prisma.config.ts | Updated as part of this pull request. |
| apps/api/pnpm-workspace.yaml | Updated as part of this pull request. |
| apps/api/package.json | Updated as part of this pull request. |
| apps/api/nest-cli.json | Updated as part of this pull request. |
| apps/api/Dockerfile.dev | Updated as part of this pull request. |
| apps/api/Dockerfile | Updated as part of this pull request. |
| apps/api/.prettierrc | Updated as part of this pull request. |
| apps/api/.prettierignore | Updated as part of this pull request. |
| apps/api/.oxlintrc.json | Updated as part of this pull request. |
| apps/api/.gitignore | Updated as part of this pull request. |
| apps/api/.env.example | Updated as part of this pull request. |
| apps/api/.dockerignore | Updated as part of this pull request. |
| .mcp.json | Updated as part of this pull request. |
| .claude/skills/to-tickets/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/to-spec/SKILL.md | Updated as part of this pull request. |
| .claude/skills/to-spec/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/tdd/tests.md | Updated as part of this pull request. |
| .claude/skills/tdd/SKILL.md | Updated as part of this pull request. |
| .claude/skills/tdd/mocking.md | Updated as part of this pull request. |
| .claude/skills/tdd/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/research/SKILL.md | Updated as part of this pull request. |
| .claude/skills/research/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/implement/SKILL.md | Updated as part of this pull request. |
| .claude/skills/implement/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/implement-spec/SKILL.md | Updated as part of this pull request. |
| .claude/skills/implement-spec/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/handoff/SKILL.md | Updated as part of this pull request. |
| .claude/skills/handoff/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/grilling/SKILL.md | Updated as part of this pull request. |
| .claude/skills/grilling/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/grill-with-docs/SKILL.md | Updated as part of this pull request. |
| .claude/skills/grill-with-docs/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/grill-me/SKILL.md | Updated as part of this pull request. |
| .claude/skills/grill-me/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/domain-modeling/SKILL.md | Updated as part of this pull request. |
| .claude/skills/domain-modeling/GLOSSARY-FORMAT.md | Updated as part of this pull request. |
| .claude/skills/domain-modeling/agents/openai.yaml | Updated as part of this pull request. |
| .claude/skills/domain-modeling/ADR-FORMAT.md | Updated as part of this pull request. |
| .claude/skills/codebase-design/DESIGN-IT-TWICE.md | Updated as part of this pull request. |
| .claude/skills/codebase-design/DEEPENING.md | Updated as part of this pull request. |
| .claude/skills/codebase-design/agents/openai.yaml | Updated as part of this pull request. |
| .claude/settings.json | Updated as part of this pull request. |
🧠 Review effort: Lite
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+1
to
+13
| import { INestApplication } from '@nestjs/common'; | ||
|
|
||
| /** Prefixo e versão de todas as rotas (seção 3.1 do docs/lld.md). */ | ||
| export const API_PREFIX = 'v1'; | ||
|
|
||
| /** | ||
| * Configuração da aplicação HTTP que vale tanto para o `main.ts` quanto para a | ||
| * base de testes. O que depende de injeção (filtro de erros, validação de | ||
| * entrada) é registrado no `AppModule`. | ||
| */ | ||
| export function configureApp(app: INestApplication): void { | ||
| app.setGlobalPrefix(API_PREFIX); | ||
| } |
| * constructor(@Inject(mailConfig.KEY) config: ConfigType<typeof mailConfig>) | ||
| */ | ||
| export class AppConfigModule { | ||
| static forRoot(options: AppConfigModuleOptions = {}): Promise<DynamicModule> { |
| import { SessionsService, type TokenPair } from './sessions.service.js'; | ||
|
|
||
| @Controller('auth') | ||
| @UseGuards(ClientIpGuard) |
Comment on lines
+51
to
+55
| if (unverified) { | ||
| await this.sendVerification(user); | ||
| } else { | ||
| this.mailer.sendAlreadyRegistered(user.email); | ||
| } |
Comment on lines
+15
to
+18
| execFileSync('node_modules/.bin/prisma', ['migrate', 'deploy'], { | ||
| env: { ...process.env, DATABASE_URL: testDatabaseUrl }, | ||
| stdio: 'pipe', | ||
| }); |
| async function requestLink( | ||
| formData: FormData, | ||
| send: (input: { email: string }) => Promise<ApiResult<void>>, | ||
| pending: typeof PENDING_VERIFICATION, |
Comment on lines
+5
to
+15
| First, run the development server: | ||
|
|
||
| ```bash | ||
| npm run dev | ||
| # or | ||
| yarn dev | ||
| # or | ||
| pnpm dev | ||
| # or | ||
| bun dev | ||
| ``` |
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.


No description provided.