mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 22:06:38 +08:00
9.7 KiB
9.7 KiB
Wavelet Agent Index
This file is the project-level guide for agents working in Wavelet. More
specialized workflows still live in .agent/skills/.
Always Read The Matching Skill
new-async-task: use when adding or changing Asynq tasks, scheduled jobs, task metadata, task payload validation, task logs, task retry behavior, or Admin task APIs.new-setting: use when adding or changing startup config, database-backed system/business/public settings,/admin/systemparameters, or/admin/settingsgraphical settings.- Go skills: use the focused
go-*skills for Go implementation details such as testing, error handling, packages, context, concurrency, logging, documentation, and review. shadcn: use when adding, changing, or composing shadcn/ui components.
Non-Negotiable Project Guardrails
- Do not delete
frontend/node_modules; reinstall withpnpm installif dependencies need refreshing. - Keep
internal/util/framework-free. Do not import Gin, GORM, sessions, or other HTTP/framework packages frominternal/util/or its subpackages. - Register all HTTP routes only in
internal/router/router.go. - Update Swagger (
make swagger) when API handlers change. - Run
make code-checkbefore submitting changes.
Quick Commands
| Command | When |
|---|---|
make code-check |
Required before submit |
make build-test |
Functional build verification |
make swagger |
After adding/changing APIs |
make build-embedded |
Release binary with embedded frontend |
make license |
After adding Go files |
make license-check |
CI/license validation |
Wavelet Project Development Guide
Use this guide for ordinary Wavelet development. If the task is specifically
about Asynq/background/scheduled tasks, use new-async-task as the detailed
workflow.
Tech Stack
- Backend: Go 1.25+, Gin, GORM, PostgreSQL, optional ClickHouse, Redis, Asynq, Cobra, Viper, Swaggo, OpenTelemetry, Zap, AWS SDK v2, Snowflake IDs.
- Frontend: Next.js App Router, TypeScript, Tailwind CSS, pnpm, shadcn/ui.
Directory Map
Top level:
main.go: program entry, delegates tointernal/cmd.config.example.yaml: committed config template. Keep it updated when adding config fields.config.yaml: local runtime config. Do not treat it as committed source.docker/: integrated, frontend-only, and backend-only Dockerfiles.docs/: generated Swagger docs. Do not hand edit generated files.frontend/: Next.js app.internal/: private Go backend code.scripts/: local and CI helper scripts.support-files/: auxiliary deployment files.
Backend:
internal/cmd/: Cobra commands for API, worker, scheduler, root init.internal/config/: Viper loading and config structs. Runtime code should useconfig.Config.<Section>.<Field>.internal/router/: the only HTTP route registration point.internal/apps/: feature modules and HTTP handlers.internal/model/: GORM entities and model-level business methods.internal/db/: PostgreSQL, Redis, ClickHouse, GORM logging, ID generation, and AutoMigrate wiring.internal/storage/: S3-compatible storage and cache abstraction.internal/task/: Asynq task framework; seenew-async-taskfor changes.internal/service/: complex business services when handlers/models are too narrow a home.internal/common/: shared response, bind, constants, and common errors.internal/util/: pure utilities with no framework imports.internal/logger/: Zap and OTel logging helpers.internal/listener/: event listeners and message/webhook consumers.internal/otel_trace/: tracing helpers.
Frontend:
frontend/app/: App Router pages, route groups, root layout, globals.frontend/components/ui/: shadcn/ui base components.frontend/components/common/: cross-page business components.frontend/components/layout/: Header, Sidebar, Footer, app layout pieces.frontend/components/auth/,home/,animate-ui/,providers/: scoped UI.frontend/contexts/,hooks/,lib/,types/,public/: shared state, hooks, clients/utilities, TypeScript types, static assets.
Important common components:
components/common/admin/tasks.tsx: task dispatch UI.components/common/admin/task-executions.tsx: task execution log/retry UI.components/common/admin/system.tsx: system config management.components/common/admin/users.tsx: user management.components/common/general/manage-pannel.tsx: generic list/detail manager.components/common/general/password-dialog.tsx: sensitive-action password confirmation dialog.components/common/settings/system-settings.tsx: admin system settings.
Backend Rules
Naming:
- Go packages and files use lowercase snake words:
auth_source,postgres_logger.go. - Exported Go identifiers use PascalCase; unexported identifiers use camelCase.
- Request/response structs use camelCase with suffixes like
listUsersRequestandlistUsersResponse. - Error message constants are camelCase string
constvalues, not package-levelerrorvalues. - YAML config keys use lowercase snake case.
Handlers:
- Handler names are verb + noun, for example
ListUsers. - Bind with
ShouldBindQueryorShouldBindJSON. - Return success through
util.OK(data),util.OKNil(), orresponse.RespondSuccess. - Return failures with
util.Err(msg)orresponse.RespondFailure. - API responses must have the outer shape
{ "error_msg": "", "data": ... }. - Pagination responses use
{ "total": 0, "results": [] }underdata. - Every HTTP API needs complete Swagger comments; run
make swaggerafter API changes.
Routes and modules:
- Register routes only in
internal/router/router.go. - In
internal/apps/<module>/, use:routers.goorcontrollers.gofor HTTP handlers.middlewares.gofor module-specific middleware.errs.gofor string error constants only.constants.gofor non-error business constants.
- For Admin modules, prefer
internal/apps/admin/<module>/. - If a handler file exceeds 600 lines, contains complex multi-step logic, or
mixes independent domains, split business logic into
logic.goorlogics.go. Keeprouters.goto binding, calling logic, and responding.
Middleware:
- Global middleware belongs in router setup:
gin.Recovery(),otelgin.Middleware(), logger middleware, and session middleware. - Use
oauth.LoginRequired()for logged-in route groups. - Use
admin.LoginAdminRequired()for Admin route groups.
Config:
- Runtime code reads config from
config.Config, never directly fromos.Getenv(). - When adding config, update both
config.example.yamlandinternal/config/model.go.
Database:
- Simple queries may use GORM directly from the model layer.
- Admin code should prefer
db.DB(ctx)to get tracing-aware DB access. - Do not put complex SQL in handlers; move it to
internal/model/orinternal/service/. - Use AutoMigrate wiring under
internal/db/migrator/; do not add manual DDL. - Do not create physical database foreign keys. Add explicit indexes for relation fields instead.
- Database defaults must match Go model zero values (
nil,0,false,"") to avoid surprising inserts.
Strict dependency guard:
internal/util/and its subpackages must stay framework-free.- Do not import
github.com/gin-gonic/gin,gorm.io/gorm,github.com/gin-contrib/sessions, or HTTP middleware/framework packages frominternal/util/. - If utility logic needs web glue, keep pure validation/calculation in
internal/util/and put Gin middleware/response handling ininternal/apps/.
Admin module workflow:
- Define or extend models in
internal/model/. - Register AutoMigrate changes under
internal/db/migrator/. - Create
internal/apps/admin/<module>/routers.goand optionalerrs.go. - Register routes in
internal/router/router.go. - Run
make swagger.
Frontend Rules
Styling:
- shadcn/ui base components should use their
variantsystem and global CSS variables. Do not hardcode colors, backgrounds, or shadows in businessclassNamewhen a component variant should own the look. - If an existing variant is insufficient, extend the shadcn/ui component variant instead of hardcoding one-off colors.
- Use Lucide icons for common icon needs. Put custom icons in
frontend/components/icons/as named exports.
Page width:
- Page root containers must support full width. Use
w-full. - Do not hardcode page-level max widths like
max-w-6xlormax-w-4xl; the main layout owns the normal/full-width constraint.
Component placement:
- Cross-page business components belong in
frontend/components/common/. - shadcn/ui primitives belong in
frontend/components/ui/. - Route/page-specific components belong in the closest feature directory.
Type safety:
- Do not use
any. - Use
unknownonly with explicit narrowing or type assertions before use. - Use
neversparingly and document why when it is non-obvious. - Frontend changes must pass TypeScript and ESLint checks.
Services:
- Frontend API access goes through service classes and the exported
servicesobject. - Create new services as:
frontend/lib/services/<service-name>/
types.ts
<service-name>.service.ts
index.ts
- Service classes extend
BaseService, definebasePath, and expose typed static methods. - Register the new service in
frontend/lib/services/index.ts.
Quality Gates
make code-check: required before submit; frontend typecheck + ESLint and backend golangci-lint.make build-test: build verification for frontend and Go backend.make swagger: regenerate Swagger after API changes.make build-embedded: release binary with frontend static export embedded.make license: run after adding Go files.make license-check: validate Go license headers.
Never delete frontend/node_modules; refresh dependencies with pnpm install.