Files
HIPCTF2/.kilo/plans/870.md
T

3.9 KiB

Fix Plan: TS2459 PostFormSubmitPayload not exported

1. Root Cause

frontend/src/app/features/admin/blog/blog-form.pure.ts declares PostFormSubmitPayload and PostFormMode as exports, but frontend/src/app/features/admin/blog/blog-form-modal.component.ts only imports them — it does not re-export them.

frontend/src/app/features/admin/blog/blog.component.ts:10 imports PostFormSubmitPayload from ./blog-form-modal.component, which has no such export. Under ng build --configuration production (which uses compilationMode: "full" Angular strict template/type-check), this is a hard TS2459 error and the bundle fails.

The existing codebase convention is the opposite: category-form-modal.component.ts declares CategoryFormSubmit / CategoryFormMode inside the modal file and consumers (categories.component.ts) import them from the modal component directly. My initial layout diverged from that pattern by colocating the modal-output types in the .pure.ts module.

2. Fix (chosen approach: match the existing CategoryFormSubmit convention)

Move the two UI-emit types out of blog-form.pure.ts and into blog-form-modal.component.ts, then update the two importers.

2.1 frontend/src/app/features/admin/blog/blog-form-modal.component.ts (modify)

Add at the top (right after the existing imports from ./blog-form.pure):

export type PostFormMode = 'create' | 'edit';

export interface PostFormSubmitPayload {
  mode: PostFormMode;
  title: string;
  bodyMd: string;
  action: 'draft' | 'publish';
}

Remove these two names from the import list at line 19-20:

// before
import {
  PostFormGroup,
  PostFormMode,        // ← remove
  PostFormSubmitPayload, // ← remove
  buildPostBody,
  syncPostForm,
  validatePostForm,
} from './blog-form.pure';

// after
import {
  PostFormGroup,
  buildPostBody,
  syncPostForm,
  validatePostForm,
} from './blog-form.pure';

PostFormGroup stays imported from the .pure.ts module (it is the pure form-shape type, used internally by the modal).

2.2 frontend/src/app/features/admin/blog/blog-form.pure.ts (modify)

Remove the two declarations (lines 4 and 11-16) so the pure module no longer leaks UI-emit types:

  • Delete export type PostFormMode = 'create' | 'edit';
  • Delete the entire export interface PostFormSubmitPayload { ... } block.

Keep the rest of the file unchanged:

  • PostFormGroup
  • MAX_TITLE_LENGTH / MAX_BODY_LENGTH
  • validatePostForm, syncPostForm, buildPostBody, statusBadgeClass, statusLabel

2.3 No other edits required

  • frontend/src/app/features/admin/blog/blog.component.ts already imports PostFormSubmitPayload from ./blog-form-modal.component — after step 2.1 that import resolves correctly. No change.
  • tests/frontend/blog-admin-form.spec.ts does not import PostFormMode or PostFormSubmitPayload (verified — only PostFormGroup, buildPostBody, statusBadgeClass, statusLabel, syncPostForm, validatePostForm). No change.
  • tests/frontend/blog-page.spec.ts is unaffected.

3. Verification

After the fix:

  1. cd /repo && npx ng build --configuration production must succeed (the original failing command).
  2. cd /repo && npm test must continue to pass (89 suites, 678 tests).
  3. The BlogFormModalComponent.submit output still emits the same PostFormSubmitPayload shape — blog.component.ts:onFormSubmit is unchanged.

4. Why this fix over the alternative

Alternative considered: change the import in blog.component.ts from './blog-form-modal.component' to './blog-form.pure'. This is a one-line change but it diverges from the established CategoryFormSubmit pattern (modal-emit types live with the modal), and it forces every future consumer of the form payload to import from the .pure.ts module instead of the modal. The chosen fix aligns this feature with the rest of the codebase and keeps the modal's public API self-contained.