chore: adding docs
This commit is contained in:
parent
23816d00f7
commit
81c5112409
39 changed files with 7257 additions and 2 deletions
124
data/docs/go-guess-copilot-instructions.md
Normal file
124
data/docs/go-guess-copilot-instructions.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<!-- go-doc:generated:begin source=go-guess:.github/copilot-instructions.md signature=781b9d03c5914e6fd446714cc17f6867 generated=2026-10-05 18:14 UTC -->
|
||||
Imported from .github/copilot-instructions.md in the go-guess repository.
|
||||
|
||||
---
|
||||
|
||||
# Copilot instructions
|
||||
|
||||
## Build, test, and lint
|
||||
|
||||
Run repository-wide commands from the root:
|
||||
|
||||
```bash
|
||||
make dev # run PostgreSQL, RabbitMQ, API, and frontend with development fixtures
|
||||
make test # complete suite, including disposable infrastructure integration tests
|
||||
make test-integration # Go tests; starts PostgreSQL and RabbitMQ Testcontainers
|
||||
make test-env # isolated seeded UI stack at http://localhost:15173
|
||||
make test-env-down # remove the test stack and its PostgreSQL volume
|
||||
make lint # go vet and ESLint
|
||||
make build # compile the API and production frontend
|
||||
```
|
||||
|
||||
Focused tests:
|
||||
|
||||
```bash
|
||||
cd backend && go test ./internal/service -run '^TestCandidatesRequireSixtyPercent$'
|
||||
cd backend && go test -tags=integration ./internal/integration -run '^TestCompleteInterviewWorkflow$'
|
||||
cd frontend && npm test -- src/app/App.test.tsx -t "filters jobs by title"
|
||||
```
|
||||
|
||||
The required toolchain is Go 1.27.1 and React 19.3 with TypeScript/Vite. Use
|
||||
`cd frontend && npm run format:check` for frontend formatting and `gofmt` for Go.
|
||||
|
||||
## Architecture
|
||||
|
||||
- `backend/cmd/api` wires configuration, PostgreSQL, security, services, handlers,
|
||||
and the Chi router. Requests flow through `internal/web/{router,handler,model,mapper}`
|
||||
to `internal/service/{model,services}` and then
|
||||
`internal/database/{repository,mapper,entity}`. Never expose GORM entities from
|
||||
handlers.
|
||||
- `backend/cmd/seed` applies embedded environment-aware fixtures.
|
||||
- `backend/internal/eventbus` publishes note and shared-document events to the
|
||||
durable `go-guess.interview-events` RabbitMQ fanout exchange. Each API instance
|
||||
consumes through its own exclusive queue and distributes interview-filtered
|
||||
events to authenticated interviewer SSE streams or token-authorized participant
|
||||
streams.
|
||||
- `frontend/src/app` owns application routing and providers, `src/features` groups
|
||||
feature pages and components, `src/components` contains reusable UI,
|
||||
`src/api/client.ts` is the typed HTTP boundary, `src/types` contains client
|
||||
domain types, and `src/styles/global.css` contains application-wide styles.
|
||||
Keep feature-specific components inside their feature directory. Vite proxies
|
||||
`/api` to the Go service in development.
|
||||
- Multi-tenant URLs use `<tenant>.<app domain>`, where the app domain is
|
||||
`guess-dev.urpi.be` in local development and the Kubernetes development
|
||||
profile, and `guess.urpi.be` in production. The frontend derives the tenant from
|
||||
the hostname, calls same-origin `/api` through the HTTPS proxy, and sends
|
||||
`X-Tenant-Id` on every request type. Generated participant links must use the
|
||||
validated matching tenant origin. Keep this contract documented in `README.md`
|
||||
and `frontend/README.md`.
|
||||
- Protected interviewer routes require a bearer JWT only. Go Loose is used for
|
||||
browser login, not for API-key authorization.
|
||||
|
||||
Goose files in `backend/migrations` are schema-only and run in every environment.
|
||||
`internal/database/seed/common.sql` contains shared reference data;
|
||||
`development.sql` and `test.sql` contain idempotent environment-specific fixtures.
|
||||
Every entity change requires a migration plus corresponding fixture and integration
|
||||
test updates. Never put demo users or test records in schema migrations.
|
||||
|
||||
Authentication uses bcrypt passwords and HMAC-signed bearer JWTs. Domain routes are
|
||||
protected except `/api/health`, `/api/openapi.json`, `/api/auth/login`,
|
||||
`/api/auth/callback`, `/api/auth/logout`, `/api/auth/session`, and opaque-token
|
||||
participant interview routes. Any tenant host starts browser login with
|
||||
`github.com/danyel/go-loose/client`: `/api/auth/login` redirects to
|
||||
`https://<tenant>.<GO_LOOSE_AUTH_DOMAIN>/connect/authorize` and Go Loose returns to
|
||||
`/api/auth/callback`. `GO_LOOSE_AUTH_DOMAIN` is `auth-dev.urpi.be` locally and in
|
||||
the development profile, and `auth.urpi.be` in production; `GO_LOOSE_APP_DOMAIN`
|
||||
is the matching application domain. Both default to the development domains.
|
||||
`GET /api/auth/session` answers `404` when no Go Loose login is configured for the
|
||||
request host, and the frontend uses that to fall back to the password form instead
|
||||
of redirecting. Go Loose client credentials come from uncommitted environment
|
||||
variables. The tenant comes from `X-Tenant-Id`, or from the request host and
|
||||
`X-Forwarded-Host` when the header is absent; missing tenant context uses the
|
||||
public schema. Never expose password hashes, CV/photo bytes, or interviewer
|
||||
reference answers in public JSON.
|
||||
|
||||
Questions are permanent reusable records linked to jobs through
|
||||
`job_posting_questions`; detach links rather than deleting questions. Deprecated
|
||||
questions remain searchable but cannot be newly attached. Question values are
|
||||
`open`, `multiple_choice`, `radio`, and `code_review`. Choice types require at least
|
||||
two options. Open/code-review types require `referenceAnswer`; code review also
|
||||
requires `codeSnippet`.
|
||||
|
||||
Jobs move through `draft`, `published`, and `deprecated`. Publishing requires a
|
||||
question, only published jobs can create invitations, and candidate matching uses
|
||||
labels plus both skill groups with a 60% threshold. Invitation URLs use
|
||||
`/participant/:invitationId`, where the identifier is an opaque token. Participant
|
||||
questions are acceptance-gated and answers are saved before final submission;
|
||||
interviewer review uses
|
||||
`GET /api/jobs/{id}/invitations/{invitationId}`.
|
||||
|
||||
Only completed assessment invitations can receive a `passed` or `failed` outcome,
|
||||
and only passed candidates can be scheduled for an interview. Scheduled
|
||||
interviews include the creator plus selected co-interviewers. Attendees manage
|
||||
their invitation through `/api/invitations`, see accepted interviews in `/api/schedule`,
|
||||
and can write notes only after the interview has started. Notes are private to
|
||||
authenticated attendees. The opaque `/participant/meeting/:candidateToken` view
|
||||
exposes only candidate-safe schedule and shared-document data.
|
||||
|
||||
## Repository conventions
|
||||
|
||||
- Prefix every Go interface name with `I`.
|
||||
- Keep web, service, and persistence models separate and convert them in adjacent
|
||||
`mapper` packages.
|
||||
- Participant creation uses multipart fields `firstName`, `lastName`, `birthday`,
|
||||
`email`, `contactInfo`, `photo`, and `cv`.
|
||||
- Return explicit errors; map expected failures to HTTP status codes and log
|
||||
unexpected failures instead of silently falling back.
|
||||
- Update the directly related local documentation whenever behavior,
|
||||
configuration, architecture, commands, or public API surfaces change.
|
||||
- Register backend routes through the typed OpenAPI-aware router helper. The
|
||||
runtime `/api/openapi.json` document is the API source of truth; do not add a
|
||||
manually maintained route inventory or require a generation command.
|
||||
- Commit every repository change with a meaningful conventional prefix such as
|
||||
`feat:`, `fix:`, `refactor:`, `test:`, `docs:`, or `chore:`.
|
||||
<!-- go-doc:generated:end -->
|
||||
Loading…
Add table
Add a link
Reference in a new issue