# CLAUDE.md — Application Repository

This file is read by Claude Code, Claude Desktop, and any other Claude-based
AI tool every time it works in this repository. Its rules are binding.

---

## 1. Database access is FORBIDDEN

This repository contains no `db/migrations/`, no `db/schema/`, and no `.sql`
files of any kind. Do NOT create them.

You do NOT have a database connection string and will not be given one. Do
NOT generate code that connects directly to a database. All data access
goes through repository classes that already exist (or that you will create
alongside this feature).

If you ever find yourself about to write `CREATE TABLE`, `ALTER TABLE`, or
any other DDL — STOP. Schema changes go through the MCP proposal flow
described in Section 3.

## 2. MCP schema server is mandatory for schema concerns

Before generating any code that introduces a new entity, a new column, a
new query pattern, or touches an unfamiliar table, you MUST consult the
central MCP schema server. The server is configured for you as `schema`.

Six tools are available:

| Tool | When to call it |
|------|-----------------|
| `find_existing_tables_for_concept(concept)` | First call before proposing any new table. Looks across all 8 schemas for tables that may already model the concept. |
| `list_tables(schema)` | When you need a list of tables in a specific schema (e.g., `common`, `sales`). |
| `describe_table(qualified_name)` | When you need columns, types, FKs, and prose description for a specific table. |
| `get_proposal(proposal_id)` | When following up on an earlier schema-change proposal. |
| `list_pending_proposals(submitter, status)` | When checking the queue. |
| `propose_table_change(operation, schema, table, columns, justification)` | When the developer has approved creating a new table or adding a column. |

If the MCP server is unreachable for any reason, STOP. Do not fall back to
generating SQL from training memory — that produces drift and silent bugs.
Tell the developer the MCP server is unreachable and wait.

## 3. The reuse-first workflow (CONSERVATIVE — required)

For any feature that may need data persistence, follow this sequence:

(a) Call `find_existing_tables_for_concept()` with a natural-language
    description of what the feature needs to store.

(b) Present the matches to the developer with clear reuse scores. Examples:
    - score > 0.80 → recommend strongly for reuse
    - score 0.50–0.80 → mention as candidate, explain pros and cons
    - score < 0.50 → likely a new table is appropriate

(c) STOP and wait for the developer to choose. Do not silently pick.

(d) On developer approval, for any new table or new column:
    - Call `propose_table_change()` with structured JSON: operation,
      schema, table, columns (name/type/nullability/defaults/constraints),
      and a one-paragraph justification.
    - Capture the returned `proposal_id` (format: `PR-NNNN`).

(e) Generate the application code that references existing tables AND the
    proposed new tables BY NAME. The application code will not run until
    the DBA approves the proposal and authors the migration — that's
    expected.

(f) Add the proposal_id to the PR description so the DBA can trace from
    PR to proposal.

## 4. When MCP is NOT needed (practical exceptions)

You may skip MCP consultation for these cases:

- Pure UI/UX changes that don't touch data layers
- Bug fixes to existing application logic where the schema is unchanged
- Refactoring within an existing service that already uses known tables
- Adding methods to an existing repository class for an existing table
- Test fixes that don't require new test data

For these, you may proceed without calling MCP. When in doubt, call MCP
anyway — querying schema is cheap and protects against drift.

## 5. Application code stack (locked in for this platform)

- **Backend / API**: .NET 8 (C#) with ASP.NET Core
- **Frontend (custom UI)**: React + TypeScript + Next.js
- **Low-code UI**: Power Apps + Power Pages (use only for admin/internal
  flows, not customer-facing)
- **Agent orchestration**: Semantic Kernel (.NET) is primary;
  LangGraph (Python) is used only by the AI Platform team
- **Chatbots**: Tiered with Copilot Studio + Bot Framework SDK +
  Semantic Kernel
- **Data access**: Entity Framework Core for command-side;
  Dapper for query-side reads
- **Database**: Azure SQL (single logical DB, multiple schemas)
- **Analytics**: Power BI
- **DevOps**: GitHub Actions (Azure DevOps available as fallback)

Generate code in the established stack. Don't introduce other ORMs, other
frameworks, other languages unless explicitly asked.

## 6. Style and structure

- C# 12 with `nullable` enabled
- Async all the way down — no sync-over-async, no `.Result`, no `.Wait()`
- One public type per file
- Data access through repository interfaces in `src/data/repositories/`
- Domain logic in `src/domain/`
- API controllers thin, delegate to application services
- Use `Result<T>` over exceptions for expected failure modes
- Every feature gets unit tests; every API endpoint gets integration tests

## 7. PR requirements

Every PR includes:

- Application code with tests
- A "Schema proposal" section in the PR description referencing the
  proposal_id (if any new tables/columns were proposed)
- A "Schema queries made" section listing the MCP tool calls and what
  they returned (so reviewers understand the reuse decisions)
- All tests passing locally

If schema changes were proposed, the PR description includes a note that
it cannot merge until the DBA approves the proposal and the migration
applies to Dev.

## 8. When in doubt

Stop and ask the developer. Producing an incorrect proposal is more
expensive than asking a clarifying question.
