Skip to content
Merged

Dev #2795

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
58ca329
AB#33877 fixes for worksheet checkbox handling in reporting
AndreGAot Aug 7, 2026
61300d7
AB#33877 address codeQL feedback
AndreGAot Aug 7, 2026
149cb26
[AB#33996] Change front-end FYE updates to use current year
plavoie-BC Aug 7, 2026
48dfa8e
[AB#33996] Add FYE column with SQL trigger
plavoie-BC Aug 7, 2026
18a0fe3
[AB#33996] Add FYE column binding to front-end
plavoie-BC Aug 7, 2026
7ed3b26
[AB#33996] Revert migration
plavoie-BC Aug 7, 2026
d82e968
[AB#33996] Add FYE Migration
plavoie-BC Aug 7, 2026
37a0708
[AB#33996] Add FYE Migration - First-Run Data Seeding
plavoie-BC Aug 7, 2026
2f0d701
[AB#33996] Support for FYE month format variations
plavoie-BC Aug 7, 2026
d5bbdfb
Merge remote-tracking branch 'origin/dev' into feature/AB#33996-appli…
plavoie-BC Aug 7, 2026
8b274d5
AB#33985 remove obsolete AI prompt assets
jacobwillsmith Aug 5, 2026
66b5089
AB#33985 move AI runtime config to database
jacobwillsmith Aug 5, 2026
010f998
AB#33985 rebuild AI models migration
jacobwillsmith Aug 5, 2026
c7dd97d
AB#33985 fix AIModels primary key migration
jacobwillsmith Aug 5, 2026
d6fcbb0
AB#33985 align AI model migration with dev
jacobwillsmith Aug 8, 2026
8ce08d6
AB#33985 align model seeding with unique name
jacobwillsmith Aug 8, 2026
c3c7a79
[AB#33996] Fix compute_applicants_fiscal_year_end SQL function
plavoie-BC Aug 10, 2026
7df777b
[AB#33996] Add FYE optional column to Grant Applicants List
plavoie-BC Aug 10, 2026
e5752fc
AB34003 Add log output for screenshot collect to work
DarylTodosichuk Aug 10, 2026
f96cd9e
AB34003 fix apps.silver.devops.gov.bc.ca references
DarylTodosichuk Aug 10, 2026
1f749b2
Merge pull request #2783 from bcgov/bugfix/AB#34003-cypress-e2e-uploads
DarylTodosichuk Aug 10, 2026
bfcaada
[AB#33653] Add External and Published Status Columns to Grant Applica…
plavoie-BC Aug 10, 2026
98a7e46
AB#33329 update how reporting configuration ordering is handled
AndreGAot Aug 10, 2026
5b88f13
Potential fix for pull request finding
AndreGAot Aug 10, 2026
535f02a
AB#33328 add some additional unit tests
AndreGAot Aug 10, 2026
c4a4107
Merge branch 'feature/AB#33329-reporting-configuration-ordering' of h…
AndreGAot Aug 10, 2026
ba9596e
AB#33979 - Moved AI Configuration tab to the AI module
hasanpour Aug 11, 2026
ccf3725
AB#33979 - Binded the back click handler with a closure-scoped callback
hasanpour Aug 11, 2026
8a9d90a
[AB#33653] SQ Quality Fixes
plavoie-BC Aug 11, 2026
092a990
[AB#33565] Tenant configuration localization for Grant Manager group
plavoie-BC Aug 11, 2026
2a738c8
[AB#33886] Bugfix for sort button layount on numeric and date type co…
plavoie-BC Aug 11, 2026
e852f3c
[AB#33914] Audit history widget should exclude initial published values
plavoie-BC Aug 11, 2026
1f5dd23
[AB#33914] CSS bugfix
plavoie-BC Aug 11, 2026
8cd298a
bugfix/AB#34036-CrashLoopAndSupplierException
JamesPasta Aug 11, 2026
4da18fb
bugfix/AB#34036-CrashLoopAndSupplierException-PS1update
JamesPasta Aug 11, 2026
78d8b6b
Merge pull request #2779 from bcgov/feature/AB#33996-applicant-FYE-co…
JamesPasta Aug 11, 2026
7670a79
Merge pull request #2777 from bcgov/bugfix/AB#33877-report-view-error
JamesPasta Aug 11, 2026
395c266
Merge pull request #2782 from bcgov/feature/ai-prompt-assets-cleanup-…
JamesPasta Aug 11, 2026
cc34faf
Merge pull request #2784 from bcgov/feature/AB#33653-status-columns
JamesPasta Aug 11, 2026
0978647
AB#32831 init CLAUDE md and update for project
AndreGAot Aug 11, 2026
feaa019
Merge pull request #2786 from bcgov/feature/AB#33329-reporting-config…
JamesPasta Aug 11, 2026
bf7e678
Merge pull request #2787 from bcgov/bugfix/AB#33979-Back-button-AI-ta…
JamesPasta Aug 11, 2026
595bfa6
bugfix/AB#34036-CrashLoopAndSupplierException-AIReview
JamesPasta Aug 11, 2026
70f161d
Merge pull request #2791 from bcgov/bugfix/AB#34036-Crashloop
JamesPasta Aug 11, 2026
9d1f0f4
AB#32831 remove watermark check
AndreGAot Aug 11, 2026
0dd08d3
Apply suggestions from code review
AndreGAot Aug 11, 2026
c91bc38
Merge pull request #2790 from bcgov/bugfix/AB#33914-audit-history
JamesPasta Aug 11, 2026
9e58736
feature/AB#33985-FixDBMigrator
JamesPasta Aug 11, 2026
3beaa90
feature/AB#33985-FixDBMigrator
JamesPasta Aug 11, 2026
bf6b69b
Merge pull request #2793 from bcgov/feature/AB#33985-FixAITables
JamesPasta Aug 12, 2026
068f14f
Merge pull request #2792 from bcgov/feature/AB#32831-add-claudemd
JamesPasta Aug 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cypress-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
workflow_dispatch:
inputs:
base_url:
description: "Override baseUrl (e.g. https://feature-branch.apps.silver.devops.gov.bc.ca/)"
description: "Override baseUrl (e.g. https://feature-branch.apps.gold.devops.gov.bc.ca/)"
required: false
type: string

Expand Down
70 changes: 32 additions & 38 deletions .github/workflows/cypress-e2e-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,20 @@ name: Cypress E2E (runner)

# Shared job called by cypress-dev/test/uat/prod.yml.
#
# Unlike Grants, this doesn't run Cypress on the GitHub-hosted runner directly —
# the Unity Grant Manager Route is IP-allowlisted to the BC Gov network, which
# GitHub-hosted runners can't reach. Instead this job launches an OpenShift Job
# Unity Grant Manager Route is IP-allowlisted to the BC Gov network, which
# GitHub-hosted runners can't reach. This GitHub job launches an OpenShift Job
# (from the unity-cypress-job Template in ce395f-tools) that runs the existing
# Unity.AutoUI Cypress suite from inside the cluster, waits for it to finish,
# and pulls the logs/screenshots back into this Actions run.
#
# This deliberately targets ce395f-tools on the Gold cluster, not d18498-tools
# on Silver, even though the app environments (dev/test/uat/prod) still run on
# Silver during the cluster migration — the Job's own baseUrl (via the
# base_url input, or each cypress-config-*.json's default) is what it tests
# against, independent of which cluster runs the Job itself. Building the CI
# plumbing against the migration target now avoids redoing it later.
# The Job pulls credentials from the unity-cypress-config Secret in ce395f-tools,
# synced from Vault (GH_UGM_CYPRESS_CONFIG) via External Secrets.
#
# Test credentials are NOT GitHub secrets — the Job pulls them from the
# unity-cypress-config Secret in ce395f-tools, synced from Vault
# (GH_UGM_CYPRESS_CONFIG) via External Secrets.
#
# OpenShift auth reuses the pipeline ServiceAccount (ce395f-tools), which
# already holds ClusterRole/edit there — covers everything this job needs
# (templates, processedtemplates, jobs, pods/log, pods/exec), no additional
# RBAC required. Its token is CYPRESS_OPENSHIFT_TOKEN and its cluster is
# CYPRESS_OPENSHIFT_CLUSTER — both repo-level (not tied to a GitHub
# Environment, and deliberately separate from the shared OPENSHIFT_CLUSTER
# var docker-build-*.yml uses, since that one still points at Silver).
# OpenShift auth reuses the pipeline ServiceAccount (ce395f-tools), which already
# holds ClusterRole/edit this covers everything the job needs (templates,
# processedtemplates, jobs, pods/log, pods/exec), no additional RBAC required.
#
# Token is CYPRESS_OPENSHIFT_TOKEN and its cluster is CYPRESS_OPENSHIFT_CLUSTER.

on:
workflow_call:
Expand Down Expand Up @@ -91,22 +80,24 @@ jobs:
- name: Wait for Cypress Job to finish
id: wait
run: |
# Don't use `oc wait --for=condition=complete/failed` here: a freshly
# created Job has no .status.conditions entries yet, and
# --for=condition=X (without an explicit =true) is satisfied the
# instant the condition is merely absent rather than false — so it
# can report "condition met" seconds after creation, long before the
# Job has actually run. Poll the numeric succeeded/failed fields
# instead, which are only set once a pod genuinely finishes.
# Wait for the Job to finish by polling the logs for a sentinel line
# the cypress container (see cypress-job-template.yaml in
# tenant-gitops-ce395f) prints a "CYPRESS_DONE exit_code=N"
# sentinel line when the test run finishes and, on failure,
# sleeps for 600s before actually exiting.
JOB_REF="${{ steps.launch.outputs.job_ref }}"
JOB_NAME="${JOB_REF#job.batch/}"
DEADLINE=$(( $(date +%s) + JOB_TIMEOUT_SECONDS ))
SUCCEEDED=0
FAILED=0
POD=""
EXIT_CODE=""

while true; do
SUCCEEDED=$(oc get "$JOB_REF" -n $TOOLS_NAMESPACE -o jsonpath='{.status.succeeded}')
FAILED=$(oc get "$JOB_REF" -n $TOOLS_NAMESPACE -o jsonpath='{.status.failed}')
if [ "${SUCCEEDED:-0}" -ge 1 ] 2>/dev/null || [ "${FAILED:-0}" -ge 1 ] 2>/dev/null; then
break
POD=$(oc get pods -n $TOOLS_NAMESPACE -l job-name="$JOB_NAME" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
if [ -n "$POD" ]; then
EXIT_CODE=$(oc logs "$POD" -n $TOOLS_NAMESPACE -c cypress 2>/dev/null | grep -o 'CYPRESS_DONE exit_code=[0-9]*' | tail -1 | cut -d= -f2 || true)
if [ -n "$EXIT_CODE" ]; then
break
fi
fi
if [ "$(date +%s)" -ge "$DEADLINE" ]; then
echo "Timed out after ${JOB_TIMEOUT_SECONDS}s waiting for $JOB_REF"
Expand All @@ -115,7 +106,12 @@ jobs:
sleep 10
done

echo "succeeded=${SUCCEEDED:-0}" >> "$GITHUB_OUTPUT"
echo "pod=${POD:-}" >> "$GITHUB_OUTPUT"
if [ "${EXIT_CODE:-1}" = "0" ]; then
echo "succeeded=1" >> "$GITHUB_OUTPUT"
else
echo "succeeded=0" >> "$GITHUB_OUTPUT"
fi

- name: Show Cypress logs
if: always()
Expand All @@ -126,15 +122,13 @@ jobs:
- name: Collect screenshots on failure
if: steps.wait.outputs.succeeded != '1'
run: |
JOB_NAME="${{ steps.launch.outputs.job_ref }}"
JOB_NAME="${JOB_NAME#job.batch/}"
POD=$(oc get pods -n $TOOLS_NAMESPACE -l job-name="$JOB_NAME" -o jsonpath='{.items[0].metadata.name}')
POD="${{ steps.wait.outputs.pod }}"
mkdir -p cypress-screenshots
oc cp "$TOOLS_NAMESPACE/$POD:/workspace/applications/Unity.AutoUI/cypress/screenshots" ./cypress-screenshots -c cypress || true

- name: Upload screenshots on failure
if: steps.wait.outputs.succeeded != '1'
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: cypress-screenshots-${{ inputs.env_name }}-${{ github.run_number }}
path: cypress-screenshots
Expand Down
63 changes: 63 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

> This is **Unity Portal**, a grant management system for the Province of British Columbia. It is NOT the Unity game engine — do not suggest UnityEngine APIs.

## Repository Layout

`applications/Unity.GrantManager/` is where almost all work happens — a self-contained ABP Framework solution with its own extensive AI-agent instructions. `applications/Unity.AutoUI/` holds Cypress E2E tests; `applications/Unity.Tools/`, `database/`, and `documentation/` round out the rest (see root `README.md` for the full layout).

**Read these before making non-trivial changes in `applications/Unity.GrantManager/`** — note this solution has its own `.github/`, separate from the root `.github/` above it:

- `applications/Unity.GrantManager/.github/copilot-instructions.md` — authoritative project overview, layering, and conventions (trust this first)
- `applications/Unity.GrantManager/.github/instructions/*.instructions.md` — path-scoped rules for C#, EF Core, JavaScript, security, testing
- `applications/Unity.GrantManager/.github/skills/*/SKILL.md` — deep-dive patterns: DDD, application layer, EF Core, testing, ABP CLI, module structure
- `applications/Unity.GrantManager/.github/agents/*.agent.md` — planning agents for features, DDD modeling, EF migrations, permissions/localization audits, test strategy, PR readiness

Where those files and this one overlap, prefer the more specific ones under `applications/Unity.GrantManager/.github/`.

## Build & Test

All commands run from `applications/Unity.GrantManager/`:

```bash
dotnet restore Unity.GrantManager.sln
dotnet build Unity.GrantManager.sln --no-restore # ~3 min, 81 projects
dotnet test Unity.GrantManager.sln --no-build # ~470 tests, ~1-2 min

# Single test project
dotnet test test/Unity.GrantManager.Application.Tests/ --no-build
```

- No PostgreSQL setup needed for tests — SQLite in-memory (most projects) or `EFCore.InMemory` (`Unity.GrantManager.Web.Tests`).
- `Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml.cs` has one expected `CS8604` warning — don't fix it unless asked.
- `Directory.Build.props` / `common.props` (repo-wide MSBuild props) already suppress `NU1701`, `MSB3277`, `CS1591` — don't re-suppress per-project.

### Local dev environment

`docker-compose.yml` + `.env.example` in `applications/Unity.GrantManager/` spin up the web app, PostgreSQL, a DB migrator, and Redis. Copy `.env.example` to `.env` and fill in secrets before running `docker compose up`.

### EF Core migrations

There are **two separate database contexts** — always specify which one:

```bash
cd applications/Unity.GrantManager/src/Unity.GrantManager.EntityFrameworkCore

dotnet ef migrations add <Name> --context GrantManagerDbContext --output-dir Migrations/HostMigrations # host/shared tables
dotnet ef migrations add <Name> --context GrantTenantDbContext --output-dir Migrations/TenantMigrations # per-tenant data
```

## Architecture

ABP Framework modular monolith, DDD-layered — see `applications/Unity.GrantManager/.github/copilot-instructions.md` and `applications/Unity.GrantManager/.github/skills/unity-module-structure/SKILL.md` for the full module list and dependency-direction diagram.

Business rules belong in Domain entities/managers, not controllers or app services. Don't call another app service within the same module — push shared logic into a domain service.

### Key conventions

C#, EF Core, JavaScript, security, and testing conventions are detailed in `.claude/rules/*.md` (loaded automatically for matching files) and `applications/Unity.GrantManager/.github/instructions/*.instructions.md`.

- **Branching**: `dev` → `test` → `main` promotion. Feature branches `feature/*`, fixes `bugfix/*`, urgent `hotfix/*`. PRs to `dev` come from `feature/*`/`bugfix/*`/`hotfix/*`; PRs to `main` only from `test` or `hotfix/*`.
- **Commit messages**: prefix with `[AB#<ID>]` extracted from the branch name (e.g. `feature/AB#32037-...` → `AB#32037`), then a short description.
10 changes: 5 additions & 5 deletions applications/Unity.AutoUI/CypressTestLauncher_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ But on your local system you still need to replace the tokens. These json files
cypress.dev.env.json

{
"webapp.url": "https://dev-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://dev-unity.apps.gold.devops.gov.bc.ca/",
"reporting.url": "{{reporting.url}}",
"test1username": REQUIRED
"test1password": REQUIRED
Expand All @@ -35,7 +35,7 @@ cypress.dev.env.json
cypress.dev2.env.json

{
"webapp.url": "https://dev2-unity.apps.silver.devops.gov.bc.ca/",,
"webapp.url": "https://dev2-unity.apps.gold.devops.gov.bc.ca/",,
"reporting.url": "{{reporting.url}}",
"test1username": REQUIRED
"test1password": REQUIRED
Expand All @@ -49,7 +49,7 @@ cypress.dev2.env.json
cypress.test.env.json

{
"webapp.url": "https://test-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://test-unity.apps.gold.devops.gov.bc.ca/",
"reporting.url": "{{reporting.url}}",
"test1username": REQUIRED
"test1password": REQUIRED
Expand All @@ -63,7 +63,7 @@ cypress.test.env.json
cypress.uat.env.json

{
"webapp.url": "https://uat-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://uat-unity.apps.gold.devops.gov.bc.ca/",
"reporting.url": "{{reporting.url}}",
"test1username": REQUIRED
"test1password": REQUIRED
Expand All @@ -77,7 +77,7 @@ cypress.uat.env.json
cypress.prod.env.json

{
"webapp.url": "https://prod-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://prod-unity.apps.gold.devops.gov.bc.ca/",
"reporting.url": "{{reporting.url}}",
"test1username": REQUIRED
"test1password": REQUIRED
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default defineConfig({
"cypress/scripts/**/*.cy.{js,jsx,ts,tsx}",
"cypress/regression/**/*.cy.{js,jsx,ts,tsx}",
],
baseUrl: "https://dev-unity.apps.silver.devops.gov.bc.ca/",
baseUrl: "https://dev-unity.apps.gold.devops.gov.bc.ca/",
defaultCommandTimeout: 20000, // Time, in milliseconds, to wait until most DOM based commands are considered timed out.
viewportWidth: 1440, // Default width in pixels.
viewportHeight: 900, // Default height in pixels.
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/config/dev.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"webapp.url": "https://dev-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://dev-unity.apps.gold.devops.gov.bc.ca/",
"environment": "DEV",
"test1username": "",
"test1password": "",
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/config/dev2.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"webapp.url": "https://dev2-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://dev2-unity.apps.gold.devops.gov.bc.ca/",
"environment": "DEV2",
"test1username": "",
"test1password": "",
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/config/prod.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"webapp.url": "https://prod-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://prod-unity.apps.gold.devops.gov.bc.ca/",
"environment": "PROD",
"test1username": "",
"test1password": "",
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/config/test.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"webapp.url": "https://test-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://test-unity.apps.gold.devops.gov.bc.ca/",
"environment": "TEST",
"test1username": "",
"test1password": "",
Expand Down
2 changes: 1 addition & 1 deletion applications/Unity.AutoUI/cypress/config/uat.json.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"webapp.url": "https://uat-unity.apps.silver.devops.gov.bc.ca/",
"webapp.url": "https://uat-unity.apps.gold.devops.gov.bc.ca/",
"environment": "UAT",
"test1username": "",
"test1password": "",
Expand Down
10 changes: 5 additions & 5 deletions applications/Unity.AutoUI/cypress/fixtures/metabase.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
"metabaseDetails": [
{
"unityEnv": "DEV",
"baseURL": "https://dev-unity-reporting.apps.silver.devops.gov.bc.ca/"
"baseURL": "https://dev-unity-reporting.apps.gold.devops.gov.bc.ca/"
},
{
"unityEnv": "DEV2",
"baseURL": "https://dev-unity-reporting.apps.silver.devops.gov.bc.ca/"
"baseURL": "https://dev-unity-reporting.apps.gold.devops.gov.bc.ca/"
},
{
"unityEnv": "TEST",
"baseURL": "https://test-unity-reporting.apps.silver.devops.gov.bc.ca/"
"baseURL": "https://test-unity-reporting.apps.gold.devops.gov.bc.ca/"
},
{
"unityEnv": "UAT",
"baseURL": "https://uat-unity-reporting.apps.silver.devops.gov.bc.ca/"
"baseURL": "https://uat-unity-reporting.apps.gold.devops.gov.bc.ca/"
},
{
"unityEnv": "PROD",
"baseURL": "https://unity-reporting.apps.silver.devops.gov.bc.ca/"
"baseURL": "https://unity-reporting.apps.gold.devops.gov.bc.ca/"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: application-service-designer
description: Designs ABP application service contracts, DTOs, authorization, and Mapperly mapping plans for Unity Grant Manager. Use when adding or changing app services, DTOs, or mapping profiles.
tools: Read, Grep, Glob, Bash
model: inherit
---

# ABP Application Service Designer Agent

You are the application-layer design specialist for Unity Grant Manager.

## Mission

Produce ABP-compliant service contracts and implementation plans using DTO-first design.

## Inputs

- Use cases and API behavior.
- Existing service interfaces and DTOs.
- Target module and permissions.

## Process

1. Propose or update `I*AppService` method signatures.
2. Define DTOs per method intent (create, update, get, list).
3. Identify authorization requirements and permission constants.
4. Define Mapperly mapper changes.
5. Define validation and business-exception boundaries.

## Output Format

1. Contract changes.
2. DTO matrix.
3. Authorization matrix.
4. Mapping profile changes.
5. Service implementation checklist.
6. Test targets.

## Guardrails

- Apply the `unity-application-layer` skill's patterns.
- Follow `applications/Unity.GrantManager/.github/instructions/csharp.instructions.md`.
- Methods must be async and end with `Async`.
- Accept/return DTOs only, never entities.
- Use Mapperly with `ObjectMapper.Map<>()`, never AutoMapper. Mapper classes inherit `MapperBase<TSource, TDest>` or `TwoWayMapperBase<T1, T2>` and are decorated with `[Mapper]`.
- This agent designs only — it does not edit files.
47 changes: 47 additions & 0 deletions applications/Unity.GrantManager/.claude/agents/ddd-modeler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: ddd-modeler
description: Designs and reviews ABP DDD models, aggregates, repositories, and domain managers for Unity Grant Manager. Use when creating or modifying entities, aggregates, repository contracts, or domain services.
tools: Read, Grep, Glob, Bash
model: inherit
---

# ABP DDD Modeler Agent

You are the DDD modeling specialist for Unity Grant Manager.

## Mission

Design or review domain models so business invariants are enforced in the correct ABP layer.

## Inputs

- Business rules and scenarios.
- Existing entities and repository interfaces.
- Target module.

## Process

1. Define aggregate boundaries and ownership rules.
2. Identify entity/value object responsibilities.
3. Propose behavior methods that enforce invariants.
4. Define repository contract additions only for aggregate roots.
5. Define domain service responsibilities (`*Manager`) where orchestration is needed.
6. Propose business error codes and exception points.

## Output Format

1. Aggregate model proposal.
2. Invariants and rule enforcement table.
3. Repository contract changes.
4. Domain manager methods.
5. Error code list.
6. Anti-pattern checks.

## Guardrails

- Apply the `unity-domain-driven-design` skill's patterns.
- Follow `applications/Unity.GrantManager/.github/instructions/csharp.instructions.md`.
- Do not generate GUIDs in entity constructors.
- Reference external aggregates by Id only.
- Keep app-service logic out of the domain model design.
- This agent designs/reviews only — it does not edit files.
Loading
Loading