From b2b8396294a615a40f7d8887129faf934123c35c Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sun, 30 Nov 2025 08:57:06 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 12 +++++ README.md | 3 ++ plugin.lock.json | 53 +++++++++++++++++++++++ skills/backend-code-organisation/SKILL.md | 45 +++++++++++++++++++ skills/kotlin-coroutines/SKILL.md | 28 ++++++++++++ skills/sql-dao/SKILL.md | 42 ++++++++++++++++++ 6 files changed, 183 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 plugin.lock.json create mode 100644 skills/backend-code-organisation/SKILL.md create mode 100644 skills/kotlin-coroutines/SKILL.md create mode 100644 skills/sql-dao/SKILL.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..5cd05a4 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "airbot-backend", + "description": "Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews.", + "version": "0.1.0", + "author": { + "name": "AIRBot Team", + "email": "zhongweili@tubi.tv" + }, + "skills": [ + "./skills" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..376894a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# airbot-backend + +Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews. diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..47ee897 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,53 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:sids/airbot:plugins/airbot-backend", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "dbf8aefd46148e32500f17eba1e1c16f6ddf3aef", + "treeHash": "289f90609f8687fc60cdb7f6f291c97652ac9950dcd4022ad62764dc4c97b859", + "generatedAt": "2025-11-28T10:28:20.951553Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "airbot-backend", + "description": "Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews.", + "version": "0.1.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "74a3da174db320acd972bc28373e913ec897d2e377357479ba6929971acecb86" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "96237082257e8e260f6201649acb283c7cc41c282cce521b5351695b833597dd" + }, + { + "path": "skills/kotlin-coroutines/SKILL.md", + "sha256": "bdd1e5e7fbf4c8649790dea7a912b7568d20ee00de6c4cd596bddeb4cc7507c7" + }, + { + "path": "skills/backend-code-organisation/SKILL.md", + "sha256": "8215c297cefdedef7d199d0060f4ab659e39e5ec0f7aebabdea299ca26cc7399" + }, + { + "path": "skills/sql-dao/SKILL.md", + "sha256": "e609ad1a3c70cc499643fa3ddbf3181365ddd3d0e9696953af45025a22f523be" + } + ], + "dirSha256": "289f90609f8687fc60cdb7f6f291c97652ac9950dcd4022ad62764dc4c97b859" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/backend-code-organisation/SKILL.md b/skills/backend-code-organisation/SKILL.md new file mode 100644 index 0000000..c252e89 --- /dev/null +++ b/skills/backend-code-organisation/SKILL.md @@ -0,0 +1,45 @@ +--- +name: backend-code-organisation +description: Kotlin backend layering and packaging guidelines +license: MIT +--- + +## Mission +- Keep backend services modular: resources handle transport, managers own business logic, and data access stays isolated. +- Maintain clean dependency flow across modules (`service` → `core` → `models`) to encourage reuse and testability. + +## Layering Principles +- **Resources**: Only translate HTTP/storage inputs to domain calls. No database or cross-service logic. Convert `SecurityContext` early. +- **Managers**: Encapsulate business rules; coordinate helpers, other managers, workflows, and DAL components. Break cycles by separating read/write responsibilities or introducing controllers. +- **Helpers/Services**: Reusable integrations (feature flags, external clients). Centralize external service calls to simplify retries and upgrades. +- **Repos/DAL/DAO**: Keep database interactions single-purpose. Compose multi-step transactions in repos/DAL; keep DAO calls single query. +- **Utils/Validators/Transformers**: Pure functions and extensions only; avoid hidden state. +- **Cache Managers**: Inject Redis/Lettuce clients, expose typed `get`/`invalidate` helpers. + +## Package & Module Structure +- Enforce lowercase package names without underscores; avoid versioned package hierarchies (`v2` folders). Prefer `managers.slots` over `managers.slots.v2`. +- Organize by responsibility: `managers`, `helpers`, `utils`, `dao`, `workflows`, etc. Mirror structure in tests. +- Module boundaries: + - `core`: managers, helpers, data access, transient models. May depend on `models`. + - `service`: Dropwizard resources, configuration, application wiring; no direct DB access. + - `console-service`: Console-specific resources/auth; depends on `core`. + - `client`: Outbound clients; depend only on `models`. + - `models`: Shared API/data contracts; no dependencies. + +## Dependency Injection & Config +- Add new Redis/Cosmos/DB configs across all environments (`db-test`, `db-dev`, `db-warehouse-prod`) and run the service locally to validate. +- Annotate injectable classes with `@Singleton` when appropriate. +- Only use `@Named` when multiple bindings of the same type exist; otherwise default bindings suffice. +- Centralize client construction in DI modules to enforce consistent timeouts and hosts. + +## Review Checklist +- Check that new features land in the correct layer and module (e.g., resources calling managers, not DAOs). +- Ensure helpers/managers do not introduce cyclic dependencies; suggest splitting read/write flows or using controller orchestrators. +- Verify repos/DAL enforce validation and error translation before returning data. +- Confirm new package or module names remain lowercase and idiomatic; flag attempts to create `v2` package forks. +- Audit DI modules for duplicate provider methods and proper scoping. + +## Tooling Tips +- `Glob` for `*.kt` within `service/` or `core/` to inspect layer usage. +- `Read` DI modules when new bindings appear to ensure wiring matches guidelines. +- `Grep` for `@Named` or direct DAO usage inside resources to catch misplaced logic. diff --git a/skills/kotlin-coroutines/SKILL.md b/skills/kotlin-coroutines/SKILL.md new file mode 100644 index 0000000..c820af0 --- /dev/null +++ b/skills/kotlin-coroutines/SKILL.md @@ -0,0 +1,28 @@ +--- +name: kotlin-coroutines +description: Coroutine usage guardrails for Kotlin backend reviewers +license: MIT +--- + +## Mission +- Preserve non-blocking performance characteristics by enforcing clear coroutine boundaries. +- Prevent thread pool exhaustion, deadlocks, and latency spikes caused by mixing blocking and suspend flows. + +## Red Flags +- Mixing blocking and suspending calls inside the same function without isolating the blocking work. +- Calling `runBlocking` anywhere other than top-level entrypoints (resources, `main`) or when explicitly bridging to blocking code with the correct dispatcher. +- Using `async { ... }.await()` immediately, or using `async` just to change dispatchers. +- Wiring `AsyncResponse` (Dropwizard) to wrap blocking DAO calls instead of true suspend flows. + +## Review Checklist +- Verify suspending chains remain suspend: bubble `suspend` up through managers/resources or wrap legacy blocking code with `withContext(Dispatchers.IO)`. +- Ensure blocking functions stay blocking all the way up the call stack; prefer dedicated blocking helpers (e.g., `getUserBlocking`) rather than ad-hoc `runBlocking`. +- When bridging to suspend from non-suspend contexts, check the dispatcher passed to `runBlocking` matches the underlying workload (usually `Dispatchers.IO`). +- Confirm `AsyncResponse` is only applied to non-blocking suspend flows (Cosmos, service clients with `await`/`executeAwait`). Flag usages that simply wrap JDBI or other blocking calls. +- Look for nested coroutine builders. Replace `async/await` pairs used sequentially with direct calls; use concurrent `async` only when awaiting later. +- Ensure dispatcher changes use `withContext`, not `async`, and that blocking calls inside suspend functions are guarded with the appropriate context. + +## Tooling Tips +- `Grep` for `runBlocking`, `.await()`, `executeSync`, or `AsyncResponse` to inspect how coroutines and blocking APIs mix. +- `Read` affected managers/resources to trace whether suspend functions bubble correctly. +- `Glob` modules like `*Manager.kt`, `*Resource.kt`, and `*Dao.kt` when you need broader context about call chains. diff --git a/skills/sql-dao/SKILL.md b/skills/sql-dao/SKILL.md new file mode 100644 index 0000000..d9c0e87 --- /dev/null +++ b/skills/sql-dao/SKILL.md @@ -0,0 +1,42 @@ +--- +name: sql-dao +description: SQL data access best practices for AIRBot reviewers +license: MIT +--- + +## Mission +- Guard database performance and correctness by enforcing disciplined DAO/DAL patterns. +- Catch regressions that risk outages: unbounded queries, missing indexes, unsafe scripts, or misuse of replicas. + +## Query Execution Standards +- Require explicit column selection (`SELECT col1, col2`) rather than `SELECT *`. +- Prefer synchronous flows within `jdbi.inTransaction {}`; avoid mixing suspend calls inside transactions. +- Enforce batching (`@SqlBatch`, `@BatchChunkSize(2000)`) for bulk inserts/updates and chunk large `WHERE IN` arguments (SQL Server limit ~2200 params). +- Validate pagination on read-heavy endpoints; flag unbounded fetches or N+1 loops. +- Ensure blocking annotations (`@BlockingClass`, `@BlockingCall`) exist for DAL/Repo classes and consumers. +- Confirm master vs. replica usage: critical writes/reads hit master; replica lag can reach 30 minutes. + +## Indexing & Performance +- Request evidence of supporting indexes for new predicates, sort columns, and pagination keys. +- Encourage use of table aliases/prefixes in JOINs to maintain clarity. +- For new queries, verify index coverage and that `updated_at` timestamps update alongside data mutations. +- Demand UTC handling for timestamps and rely on the database (`CURRENT_TIMESTAMP`) to set them. + +## Schema & DDL Expectations +- Ensure PRs document DDL changes and keep migrations incremental/backward compatible. +- Require `created_at`/`updated_at` columns, primary keys, and consider unique constraints where appropriate. +- Prefer `NVARCHAR` over `VARCHAR`; align column nullability with Kotlin model nullability. +- Advocate for foreign keys to avoid orphaned rows and use online/resumable index operations. + +## Scripts & Data Ops +- Scripts should live in dedicated packages, run transactional logic in managers/DAL, and treat CLI entrypoints as thin wrappers. +- Verify bulk update scripts log progress, support `mockRun`, wrap per-row mutations in try/catch, and notify stakeholders before production runs. + +## Related Stores +- Cosmos DB batches should rely on `BulkExecutor`; discourage ad-hoc parallel loops. +- RedisCache2 usage must reuse clients, keep TTLs under 6 hours, and avoid local caches that cannot be invalidated. + +## Tooling Tips +- `Grep` for `SELECT *`, `@SqlBatch`, `inTransaction`, or `AsyncResponse` inside DAO code to ensure patterns align. +- `Read` migration files and DAL implementations to confirm pagination, batching, and index handling. +- `Glob` `*Dao.kt`, `*Repository.kt`, `*Script.kt` to review related data access or scripting changes together.