ring:mapping-service-resources
Mapping a Go service's Service -> Module -> Resource hierarchy for dispatch-layer registration: detects modules and per-module PostgreSQL/MongoDB/RabbitMQ resources, database names, and shared databases, generates MongoDB index migration pairs (.up.json/.down.json), detects existing Postgres migrations, emits an HTML report, and offers opt-in S3 upload. Use before ring:adding-multi-tenancy on a new service. Skip for non-Go projects.
What this skill does
# Service Discovery
## When to use
- User wants to know what to provision in dispatch layer for a service
- User asks "what services/modules/resources does this project have?"
- Before running ring:adding-multi-tenancy on a new service
- User asks about MongoDB indexes in a project
## Skip when
- Not a Go project
- Task does not involve service discovery, dispatch layer, or resource mapping
- Project has no external dependencies
## Related
**Complementary:** ring:adding-multi-tenancy, ring:implementing-tasks
## Prerequisites
- Go project with go.mod in the current working directory
Scans Go project to produce dispatch layer registration data. Orchestrator executes all detection phases directly.
## Phase 1: Service Detection
```bash
# Service name
grep "ApplicationName\|ServiceName" internal/bootstrap/config.go 2>/dev/null | head -5
cat .env.example 2>/dev/null | grep -i "APPLICATION_NAME\|SERVICE_NAME" | head -3
# Service type
test -f go.mod && cat go.mod | head -3 # module path hints service purpose
ls internal/adapters/ 2>/dev/null # adapters reveal type
# Unified service check
ls components/ 2>/dev/null # multiple components = unified service
```
Output:
```
service_name: "my-service"
is_unified: true | false
components: [{name, path, applicationName}] # if unified
```
## Phase 2: Module Detection
```bash
# Strategy A: Explicit WithModule calls (preferred)
grep -rn "WithModule(" internal/ components/ 2>/dev/null
# Extract string arg: WithModule("onboarding") → module "onboarding"
# Strategy B: Component-based (if no WithModule found)
ls components/ # each component = one module
# module_name = component's ApplicationName
# Strategy C: Single-component fallback
# module_name = service ApplicationName
```
Merge: Strategy A → B fills gaps → C fallback.
## Phase 3: Resource Detection per Module
For each module, scan `{component_path}/internal/adapters/`:
```bash
# PostgreSQL: subdirectory existence
ls {base_path}postgres/ 2>/dev/null
# MongoDB
ls {base_path}mongodb/ 2>/dev/null || ls {base_path}mongo/ 2>/dev/null
# RabbitMQ
ls {base_path}rabbitmq/ 2>/dev/null
grep -l "producer\|Producer" {base_path}rabbitmq/ 2>/dev/null
grep -l "consumer\|Consumer" {base_path}rabbitmq/ 2>/dev/null
# Redis (informational only — NOT a dispatch layer resource)
ls {base_path}redis/ 2>/dev/null
```
## Phase 3.5: Database Name Detection per Module
```bash
# From bootstrap config
grep -E 'env:"POSTGRES_NAME|env:"DB_.*_NAME|env:"MONGO_NAME|env:"MONGO_.*_NAME' \
{component_path}/internal/bootstrap/config.go
# From .env.example (actual values)
grep -E "POSTGRES_NAME=|DB_.*_NAME=|MONGO_NAME=|MONGO_.*_NAME=" {component_path}/.env.example
# External datasources
grep -E "DATASOURCE_.*_DATABASE=" {component_path}/.env.example
```
Cross-reference across modules: same database name in 2+ modules = shared (provision once).
## Phase 4: MongoDB Index Detection & Migration File Generation
**Only execute if MongoDB was detected in any module during Phase 3.**
Execute the procedure in `references/mongodb-index-detection.md` — Steps 1, 2, 3, 4 only.
(Detection and local generation only; S3 upload is handled in Phase 6.)
1. **Step 1** — Detect in-code index definitions (`EnsureIndexes`, `IndexModel`, `CreateIndex`) per module.
2. **Step 2** — Detect existing local migration files in `{component_path}/scripts/mongodb/*.up.json` + `*.down.json` (fallback legacy `*.js`). LOCAL ONLY — no S3 lookup.
3. **Step 3** — Cross-reference code vs. local migration files, classify each as `covered` / `missing_migration` / `migration_only`.
4. **Step 4** — Generate one `.up.json` + `.down.json` file pair per missing index (atomic per index, NOT grouped by collection):
- Path: `{component_path}/scripts/mongodb/{NNNNNN}_{index_name}.up.json` / `.down.json` — per-module directory preserves ownership for Phase 6 upload (single-component services resolve `{component_path}` to repo root)
- Naming: `idx_{collection}_{fields}` (or `uniq_*` for uniqueness business rules)
- HARD GATE: every `.up.json` MUST have explicit `"options.name"` matching the file name
- **Track per module:** populate `module.generated_migration_files = [{up_file, down_file, index_name}, ...]` so Phase 6 knows exactly which files belong to which module
**Format reminder:** the dispatch layer reads `.up.json` / `.down.json` from S3 and applies indexes on tenant provisioning. The service does NOT execute these files. Legacy `.js` scripts are NOT uploaded — only JSON migrations.
## Phase 4.5: PostgreSQL Migration Detection
**Only execute if PostgreSQL was detected in any module during Phase 3.**
Detection only — Postgres migrations are written by developers; this skill does NOT generate `.sql` files.
```bash
# Common golang-migrate locations (per module path resolved in Phase 3)
ls {component_path}/scripts/postgres/*.up.sql 2>/dev/null
ls {component_path}/scripts/postgresql/*.up.sql 2>/dev/null
ls {component_path}/db/migrations/*.up.sql 2>/dev/null
ls {component_path}/migrations/*.up.sql 2>/dev/null
```
For each `.up.sql` file found:
- Verify the matching `.down.sql` exists (golang-migrate convention).
- Map it to its module (by directory path).
- Track for the Phase 6 upload.
Store: `module.postgres_migrations = [{up_file, down_file, sequence, description}]`
If a `.up.sql` exists without `.down.sql` → flag in Phase 5 HTML report (golang-migrate requires pairs).
## Phase 5: Generate HTML Report
Dispatch `ring:visualizing`:
```
Generate HTML report showing:
- Service: {service_name} | Unified: {is_unified}
- For each module:
- Resources table: type, repositories/collections, has_producer, has_consumer, queues
- Database names: postgres_db, mongo_db (with env var names)
- Redis: detected / not detected (note: key prefixing only)
- Shared databases: list with modules that share them
- Dispatch layer registration template (JSON)
- MongoDB index coverage table (collection / keys / code / migration / index name) per `references/mongodb-index-detection.md` "Report Section: MongoDB Index Coverage"
- PostgreSQL migration table per module: file count, missing-pair warnings (`.up.sql` without `.down.sql`)
- Upload-ready summary: total Mongo pairs and Postgres pairs to be offered for upload in Phase 6
Style: clean, data-dense table layout
```
## Phase 6: Optional S3 Upload
**Execute after Phase 5. Always opt-in — never upload without explicit user confirmation.**
```text
1. Print summary and ask:
"Ready to upload to S3:
- MongoDB: {N} index migration pairs (.up.json/.down.json) across {M} modules
- PostgreSQL: {P} migration pairs (.up.sql/.down.sql) across {Q} modules
Upload to S3? (y/n)"
2. If user declines → done. Files remain local. Report status: "Upload skipped by user."
3. If user accepts:
a. Verify AWS CLI: `aws --version`. If absent → abort, report "AWS CLI not installed."
b. Ask: "Which S3 bucket? (e.g., lerian-development-migrations)"
c. Ask: "Which environment? (staging / production)"
d. Verify access: `aws s3 ls s3://{bucket}/{env}/ 2>&1`. If access denied or 404 → abort, report error.
4. Upload Mongo files (per module, best-effort — continue on individual failures):
for each module with module.generated_migration_files populated in Phase 4:
for each {up_file, down_file} in module.generated_migration_files:
aws s3 cp {up_file} s3://{bucket}/{env}/{service}/{module}/mongodb/$(basename {up_file}) --content-type "application/json"
aws s3 cp {down_file} s3://{bucket}/{env}/{service}/{module}/mongodb/$(basename {down_file}) --content-type "application/json"
5. Upload Postgres files (per module, best-effort):
for each module with module.postgres_migrations populated in Phase 4.5:
for each {up_file, down_file} in module.postgres_migrations:
aws s3 cp {up_file} s3://{bucket}/{env}/{service}/{module}/postgresql/$(basename {up_file}) --content-type "application/sql"
aws s3 cp {down_fileRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.