Skip to content

feat: add app_type to app-config.json and address PR #100 review - #103

Merged
satyamdev10 merged 8 commits into
features_set-dp-functionfrom
fix/pr100-review-comments
Sep 4, 2026
Merged

feat: add app_type to app-config.json and address PR #100 review#103
satyamdev10 merged 8 commits into
features_set-dp-functionfrom
fix/pr100-review-comments

Conversation

@satyamdev10

Copy link
Copy Markdown
Contributor

Summary

Addresses review comments from @piyush on PR #100:

  • Add app_type field to app-config.json: The scaffolded config now includes an explicit "app_type" field ("oauth", "ui", or "function") so the app type is immediately visible without relying solely on the presence of discriminator blocks (ui_app, brevo_function, auth).

Changes

  • src/templates/files/app-config.json.tmpl — added "app_type": "{{APP_TYPE}}" field
  • src/commands/app/project-writer.ts — added {{APP_TYPE}} variable derived from ctx.uiApp / ctx.isBrevoFunction
  • src/lib/config.ts — added optional app_type field to ProjectConfig interface
  • src/__tests__/templates/conditionals.test.ts — updated template tests with {{APP_TYPE}} variable

Test plan

  • All 70 test suites pass (1534 tests)
  • ESLint clean
  • TypeScript build clean

🤖 Generated with Claude Code

satyamdev10 and others added 3 commits September 4, 2026 13:54
Add explicit `app_type` field ('oauth', 'ui', or 'function') to the
scaffolded app-config.json so the app type is immediately visible
without relying solely on the presence of discriminator blocks.

Addresses PR #100 review comment by @piyush.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `function` to app-type registry with positive `brevo_function`
  detection on both config and record paths
- Add `function` row to capability matrix (no OAuth flow, no redirect
  URIs, no account-install)
- Add `brevo_function` field to `OAuthApp` type and `AppRecordLike`
- Add `brevo function deploy` to help section
- Replace IIFE with `resolveFunctionId` in `executeFunctionAction`
- Add pagination to `fetchFunctionList` for >50 functions
- Wire `ensureFresh` into `SSEStreamDeps` for token refresh before
  SSE connections
- Expose `runEnsureFresh()` on `ApiClient`, plumb through container
- Fix comment in templates/index.ts (`brevo_function` is mutually
  exclusive with oauth, not orthogonal)
- Add explanatory comments in init.ts, tsconfig.eslint.json, help.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@piyushsarin-sib piyushsarin-sib left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the follow-up. A few points to close before this can go in.

1. PR description does not match the diff

The description lists 4 files; the diff touches 21. Beyond app_type, the branch registers function as a third app type (src/app-types/function/index.ts, contract.ts, capabilities.ts, index.ts, oauth/index.ts, ui/detect.ts, types.ts), adds ensureFresh to SSE streams, paginates fetchFunctionList, and changes root help. Please update the description to cover everything that is actually under review here (or rebase so the merge-in noise drops out).

2. app_type — two sources of truth, and BE compatibility to confirm

  • The file now carries an explicit app_type, but every detection path still runs on the block discriminators (ui_app / brevo_function / auth). Nothing reads app_type. So the two can disagree: a config with app_type: "ui" and no ui_app block is still classified OAuth. Either make the field authoritative (read it in resolveFromConfig, error on a mismatch with the blocks) or state explicitly in the interface comment that it is informational only and never consulted.
  • Please check backend compatibility for this field. Today app upload and app create build explicit payloads so app_type never reaches the wire, but confirm with the app-store BE: (a) do POST /v3/app-store/apps and POST .../upload reject or ignore an unknown app_type key if a future change spreads the config into the payload; (b) does BE want to persist/expose an explicit type on GET /cli/apps/{id} so the CLI can map it back on scaffold bootstrap instead of re-deriving it. Please note the outcome in the PR.
  • CLAUDE.md currently states "there is no appType key in app-config.json" and the ProjectConfig comment on ui_app says the same. Both need updating in this PR so the docs and the code do not disagree.

3. brevo_function needs the BE implementation to land alongside

create.ts now sends brevo_function: {} with no auth block as a third discriminator. On the deployed handler the contract is selected by sniffing for auth or ui_app, and the block validation requires at least one of those two. A body carrying only brevo_function will route to the legacy flat-OAuth flow or 400. Please raise/implement the BE side (request sniffing, block validation, snapshot persistence, echo on read) and link the ticket or PR here. This should not merge against a server that rejects the payload it sends.

4. Detection changes need tests

src/__tests__/app-types/ has nothing for the new module. Please cover:

  • isFunctionAppConfig / isFunctionAppRecord (truthy {}, absent, null, non-object).
  • Detection order: a record/config with both brevo_function and no OAuth material resolves to function, not ui.
  • oauthAppType.detectRecord now requires client_id — assert the fallthrough for a blockless record without client_id and update recoverable.test.ts if the classification changed.
  • The {{APP_TYPE}} value for the brevo_function branch in conditionals.test.ts (only oauth and ui are asserted).

5. fetchFunctionList pagination loop

while (all.length < last.total) has no guard for a page that returns zero items while total is still larger (e.g. a stale total or a server cap). That is an infinite loop of requests. Break when last.functions is empty or shorter than PAGE_SIZE. Also fetchDraftFunctionList is still hard-capped at 50 — either paginate it the same way or explain why drafts don't need it.

6. Release hygiene (repo rules)

  • No changeset on the branch. A new field in the generated app-config.json and a new help line are user-visible; run yarn changeset.
  • agent-context/SKILL.md and agent-context/AGENTS.md are untouched. Anything user-visible here (the app_type field, brevo function deploy in help) must be reflected in both in the same PR.
  • The help.ts NOTE says flipping brevo-function-type back to preview leaves the commands reachable. If that is the intended GA posture, fine, but then the gatedSection there is misleading — either add requires to the definitions or drop the gate on the help section so the two agree.

satyamdev10 and others added 3 commits September 4, 2026 14:54
- Config backward compat: legacy configs without app_type parse
  correctly (field is undefined, not an error)
- Config round-trip: app_type survives writeProjectConfig, and legacy
  configs without it stay absent after write-back
- Wire isolation: app_type never leaks into the upload payload
  (UploadAppPayload has no app_type field)
- Template rendering: brevo_function branch renders app_type correctly,
  all three app types produce the right value
- Capability matrix: function type has no OAuth/UI capabilities, only
  review-lifecycle on public distribution
- Record resolution: brevo_function record resolves to function type;
  blockless records still resolve to UI (not function)
- Recoverability: function apps are always recoverable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Aligns with the existing camelCase convention used by other config
fields (appId, appName, logoUri). The field is local metadata only
and never sent to the server, so this is a config-shape change with
no wire impact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@piyushsarin-sib

Copy link
Copy Markdown
Collaborator

Follow-up: backfill app_type for existing projects

app_type is currently write-only — the template emits it on brevo app create / brevo app scaffold, but nothing reads it and nothing adds it to a config that predates this change. Existing apps keep working (resolution still runs off the ui_app / brevo_function discriminator, and upload never sends the key), but every project scaffolded before this PR will carry an app-config.json without the field indefinitely.

Proposal: treat the first command that already writes the file back as the migration point. brevo app upload already re-writes app-config.json from the server-confirmed state (uploadProjectConfigwriteProjectConfig). When the loaded config has no app_type, derive it from the resolved type (resolveFromConfig(config).id'oauth' | 'ui' | 'function') and include it in the write-back. Same for the scaffold bootstrap write path.

Concretely:

  • app_type absent → set it from the discriminator on write-back, no prompt, no notice needed (it is descriptive metadata, not authored content).
  • app_type present and matching → leave it alone.
  • app_type present but disagreeing with the discriminator → surface a warning rather than silently overwriting, since one of the two was hand-edited.

That way a legacy project gains the field the first time it uploads, and the field can never drift from the block that actually drives behaviour. Worth adding a test alongside the existing app_type backward compatibility block in config.test.ts covering the absent → backfilled case, and updating the ProjectConfig doc comment (plus the two comments in src/lib/config.ts / src/lang/en.ts that still say there is no app-type key) to say the field is derived, not authoritative.

Comment thread src/templates/files/app-config.json.tmpl Outdated
Comment thread src/templates/files/app-config.json.tmpl Outdated

@piyushsarin-sib piyushsarin-sib left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7. CLAUDE.md — record the app-config.json casing rule and fix the stale discriminator note

Please make two edits to CLAUDE.md in this PR so the appType rename does not have to be re-derived in the next review.

(a) Add a bullet at the top of ## Key conventions:

  • app-config.json field casing: new CLI-owned fields are camelCase; only wire-mirroring keys are snake_case. Top-level fields the CLI itself defines are camelCase — appId, appName, version, logoUri, appType, auth.redirectUris. The snake_case keys are the ones that carry a platform name verbatim so they can travel on the wire unchanged — distribution_type, ui_app (and everything inside it, which is the stored snapshot field for field), brevo_function. When you add a field to src/templates/files/app-config.json.tmpl or ProjectConfig (src/lib/config.ts), pick the side it belongs to and name it accordingly; do not introduce a third style. app_type shipped snake_case and had to be renamed to appType in review (PR #103) — when reviewing a PR that adds a field to this file, leave a review comment on the casing if it breaks this rule, so it is fixed before merge rather than lived with. app upload and app create build explicit payloads, so a CLI-owned camelCase field never reaches the API; keep it that way rather than spreading the config into a request body.

(b) Fix the paragraph in the UI-apps section that begins "The presence of ui_app is the app-type discriminator" — it currently says "there is no appType key in app-config.json", which this PR makes false. Suggested replacement:

The presence of ui_app is the app-type discriminator. app-config.json also carries an appType key, but it is informational only: no detection path reads it — resolveFromConfig and every detectConfig still run on the block discriminators (ui_app / brevo_function / auth). Every branch that needs to tell the types apart goes through isUiAppConfig() in src/lib/config.ts; use it rather than testing for a key inline, so the discriminator can change in one place.

The same stale claim is in the ProjectConfig.ui_app doc comment (src/lib/config.ts) and src/templates/files/AGENTS.md.tmpl line 85 — see the inline comment on the template.

satyamdev10 and others added 2 commits September 4, 2026 15:21
- Fix doc comment in config.ts that said "there is no separate appType key"
- Fix comment in en.ts that said "there is no app-type field"
- Fix AGENTS.md.tmpl that said "There is no appType key"
- Add legacy app_type → appType migration in readProjectConfigAt
- Add 3 migration tests (read migration, write-back cleanup, precedence)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename the informational app-type field from camelCase `appType` back to
snake_case `app_type` to match the wire-mirrored key convention used by
other platform-facing fields (`distribution_type`, `ui_app`,
`brevo_function`). The migration logic now migrates the legacy `appType`
key to `app_type` on read and drops it on write-back.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
7.3% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@piyushsarin-sib piyushsarin-sib left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTGM

@satyamdev10
satyamdev10 merged commit 943781b into features_set-dp-function Sep 4, 2026
1 of 2 checks passed
@satyamdev10
satyamdev10 deleted the fix/pr100-review-comments branch September 4, 2026 10:01
@piyushsarin-sib piyushsarin-sib mentioned this pull request Sep 4, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants