Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 16 additions & 2 deletions .agents/skills/scaffold-code-app/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,20 @@ npx power-apps init -n '<APP_DISPLAY_NAME>' -e "<POWER_PLATFORM_ENVIRONMENT_ID>"

This writes `power.config.json` (`appDisplayName`, `environmentId`, `region`, etc.).

### 5. Build and push the app into a solution (optional)
### 5. Set up the quality tooling (make the app verifiable)

The Vite starter ships **no test runner** and at most a minimal linter, but every build task is gated
by `npm run verify`. Make the project verifiable now, before any feature work:

- Add **Vitest + React Testing Library + jsdom**, wired to `npm test`.
- Add **ESLint + typescript-eslint + eslint-plugin-react-hooks**, wired to `npm run lint`.
- Add an **`npm run verify`** script that runs typecheck + lint + test in one command.

See **AGENTS.md (repo root) → Stack notes** for the exact pins. After this, `npm run verify` runs
clean on the empty app, so the first task gate (Task 1) has a working harness to run against rather
than being set up live.
Comment on lines +91 to +93

### 6. Build and push the app into a solution (optional)

Publishes the built app into a Dataverse **solution**. `power-apps push` needs the solution's
**GUID** (`--solution-id`), but you should never have to find or paste a GUID — `push.mjs` resolves it
Expand Down Expand Up @@ -114,9 +127,10 @@ needs rights to push into the target solution.

- Verify `power.config.json` has the expected `appDisplayName` and `environmentId`.
- Confirm `package.json` shows `@microsoft/power-apps` at `1.2.2`.
- Confirm `npm run verify` runs clean on the empty app, so the gate is ready before Task 1.
- The app is now ready to scaffold/seed Dataverse tables and add them as data sources — see the
`dataverse-scaffold-tables`, `dataverse-create-records`, and `dataverse-add-data-source` skills.
- To publish the app into a solution, run step 5 (`push.mjs`) — typically after the tables are scaffolded
- To publish the app into a solution, run step 6 (`push.mjs`) — typically after the tables are scaffolded
into that same solution.

## Notes
Expand Down
18 changes: 16 additions & 2 deletions .claude/skills/scaffold-code-app/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,20 @@ npx power-apps init -n '<APP_DISPLAY_NAME>' -e "<POWER_PLATFORM_ENVIRONMENT_ID>"

This writes `power.config.json` (`appDisplayName`, `environmentId`, `region`, etc.).

### 5. Build and push the app into a solution (optional)
### 5. Set up the quality tooling (make the app verifiable)

The Vite starter ships **no test runner** and at most a minimal linter, but every build task is gated
by `npm run verify`. Make the project verifiable now, before any feature work:

- Add **Vitest + React Testing Library + jsdom**, wired to `npm test`.
- Add **ESLint + typescript-eslint + eslint-plugin-react-hooks**, wired to `npm run lint`.
- Add an **`npm run verify`** script that runs typecheck + lint + test in one command.

See **AGENTS.md (repo root) → Stack notes** for the exact pins. After this, `npm run verify` runs
clean on the empty app, so the first task gate (Task 1) has a working harness to run against rather
than being set up live.
Comment on lines +91 to +93

### 6. Build and push the app into a solution (optional)

Publishes the built app into a Dataverse **solution**. `power-apps push` needs the solution's
**GUID** (`--solution-id`), but you should never have to find or paste a GUID — `push.mjs` resolves it
Expand Down Expand Up @@ -114,9 +127,10 @@ needs rights to push into the target solution.

- Verify `power.config.json` has the expected `appDisplayName` and `environmentId`.
- Confirm `package.json` shows `@microsoft/power-apps` at `1.2.2`.
- Confirm `npm run verify` runs clean on the empty app, so the gate is ready before Task 1.
- The app is now ready to scaffold/seed Dataverse tables and add them as data sources — see the
`dataverse-scaffold-tables`, `dataverse-create-records`, and `dataverse-add-data-source` skills.
- To publish the app into a solution, run step 5 (`push.mjs`) — typically after the tables are scaffolded
- To publish the app into a solution, run step 6 (`push.mjs`) — typically after the tables are scaffolded
into that same solution.

## Notes
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ paraphrase the spec; the section numbers are stable, use them.
- **Per task:** typecheck + lint (near-instant). **On the data-layer task:** the audit pass (the
checklist in tasks.md Task 1). The test suite exists from Task 1's smoke test and peaks at the
modal milestone (Task 3).
- **Commit each task when its gate is green.** After `npm run verify` passes (and the audit pass where
the task requires it), commit that task with a short message naming it, before starting the next.
The git log is the build record; never bundle two tasks into one commit.
- Let the generated types and `tsc` catch drift. Prefer deleting and regenerating over hand-editing
generated files.

Expand Down
64 changes: 60 additions & 4 deletions DEMO-PLAN.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,60 @@
1. /dataverse-scaffold-tables
2. /dataverse-create-records
3. /scaffold-code-app
4. /dataverse-add-data-source
# Demo run sheet — EPPC26 Session Feedback Code App

Build a governed Power Apps Code App live, from an empty environment, directed not typed.

## Before you start (the skeleton)

- This repo is the **harness only**: `AGENTS.md` (how we build), `specs/` (what to build), and the
mirrored `.agents/skills` + `.claude/skills`. There is **no Code App and no Dataverse tables yet**.
- The Power Platform environment has **no solution and no tables**. The demo creates them.
- One **cheap, fast model** runs the whole build, on purpose: it proves the harness matters more than
the model.

## The run-through

### Setup (3 skills)

1. **`/dataverse-scaffold-tables`** — signs in (`npx power-apps login`), then creates the solution,
the option sets, both tables, and the relationship. This is the **Beat 2 failure-and-fix** moment
(harness off, then on).
2. **`/dataverse-create-records`** — seeds the sessions.
3. **`/scaffold-code-app`** — clones the Vite starter, pins the SDK, inits the app against the
environment, and **sets up the quality tooling** so `npm run verify` (typecheck + lint + test) runs
clean on the empty app.

### Build-verify loop (4 tasks, one at a time)

4. **Complete Task 1** — data layer. Opens by running `/dataverse-add-data-source`, then proves the
read path, adds the smoke test, and runs the **audit pass** ("agents auditing agents").
5. **Complete Task 2** — home list (sessions as cards).
6. **Complete Task 3** — rate modal + submit. The **test milestone**.
7. **Complete Task 4** — EPPC branding (the design payoff).

Each task: the agent reads `AGENTS.md`, then the task file, builds only that scope, runs
`npm run verify`, **commits when the gate is green**, and **stops**. You review, then run the next.
Never batch tasks.

### Deploy + the live proof

- `npm run build`, then `power-apps push` into the same solution.
- Open the governed URL: show **Entra sign-in working** and a **real rating writing to Dataverse**,
the card flipping to its rated state.
- Land it: **"I didn't write this. I directed it."**

## Why this is trustworthy (the teaching points)

- **One deterministic gate**, `npm run verify`, at every task. The trust comes from the checks, not
from eyeballing the code.
- **The git log** shows four clean commits the agent made, each behind a passing gate. Scroll it on
stage: directed, not typed.
- **No CI or git hook** — the build is throwaway and local, so the verify gate is the enforcement.
- **No "evals"** — the app has no AI inside it, so tests are the right tool; evals are for generated
output.

## Highest dry-run risks (re-check on the day)

- Exact `add-data-source` verb/flags under the npm `power-apps` CLI.
- `power-apps` global vs `npx power-apps`; pin the package version.
- The Vite template ships no test runner and only a minimal linter — `scaffold-code-app` must add
Vitest/RTL/jsdom + ESLint and the `verify` script.
- Node 22+ required.
19 changes: 11 additions & 8 deletions specs/tasks/task-1-data-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

**Goal:** the two Dataverse tables become typed data sources the app can read and write; no UI yet.

> **Start here:** run the `dataverse-add-data-source` skill to add `eppc_session` then `eppc_feedback`
> as data sources, which generates the typed `Model`/`Service` files the rest of this task builds on.
> Setup already created the tables, seeded them, and scaffolded the app with its tooling; this is the
> first build task.

**Implements:**
- [../dataverse-schema.md §8](../dataverse-schema.md) — the generated `Eppc_sessionsService` /
`Eppc_feedbacksService` contracts (read sessions, read feedback for a session, create feedback).
Expand All @@ -16,19 +21,17 @@

**Scope (what must exist, not how to build it):**
- Both tables are typed data sources with their generated `Model`/`Service` files committed —
`Eppc_sessionsModel`/`Service` and `Eppc_feedbacksModel`/`Service`. The `dataverse-add-data-source`
skill owns the command; this task only names the tables to add (`eppc_session`, then
`eppc_feedback`).
`Eppc_sessionsModel`/`Service` and `Eppc_feedbacksModel`/`Service` (produced by the
`dataverse-add-data-source` run above).
- A read path proves the seeded sessions come back typed and ordered by `eppc_starttime`. With no UI
yet, prove it somewhere disposable (console or a throwaway dev view) — the durable read UI is Task 2.
- The write contract Task 3 depends on is present and type-correct: `Eppc_feedbacksService.create`
exists, the lookup is expressed as `@odata.bind`, and Choice fields are integers — so the heavy
write task starts from a known-good signature.
- The test runner is in place: **Vitest + React Testing Library + jsdom** wired to `npm test`
(AGENTS.md Stack notes), proven by one smoke test that mocks the generated service and asserts the
read path returns typed sessions ordered by `eppc_starttime`. This gives the data layer its own
automated gate and confirms the harness works, so the Task 3 milestone runs against a configured
harness rather than one set up live.
- One smoke test proves the data layer: mocking the generated service, it asserts the read path
returns typed sessions ordered by `eppc_starttime`. The test runner itself was set up by
`scaffold-code-app`; this task just adds the first test, giving the data layer its own automated
gate so the Task 3 milestone runs against an already-exercised harness.

**Done when:**
- `tsc` is clean.
Expand Down