Skip to content

feat(catalog): creation - #14

Merged
bprahul017 merged 1 commit into
devfrom
feat/company
Sep 1, 2026
Merged

feat(catalog): creation#14
bprahul017 merged 1 commit into
devfrom
feat/company

Conversation

@athulrajtflycatchtech

Copy link
Copy Markdown

Changes

  • add catalog management features including forms and lists for applications, openings, employee testimonials, email configuration, email templates, news categories, resources, and memberships; enhance navigation and API integration for improved content administration.

Reviewer

@bprahul017 & @Sinoj-flycatch

…sts for applications, openings, employee testimonials, email configuration, email templates, news categories, resources, and memberships; enhance navigation and API integration for improved content administration
@bprahul017
bprahul017 merged commit eda9678 into dev Sep 1, 2026
3 of 4 checks passed
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add end-to-end catalog management for ten content domains

✨ Enhancement 📝 Documentation 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Adds permission-aware administration workflows for ten catalog domains.
• Exposes authenticated CRUD and published-only public APIs backed by new relational models.
• Defines versioned contracts and validates routing, accessibility, authorization, media, and
 integrations.
Diagram

graph TD
  Admin["Admin user"] --> UI["Admin catalog UI"] --> API["Catalog API"] --> Services["Catalog services"] --> DB[("PostgreSQL")]
  Public["Public client"] --> API
  Contracts["OpenAPI specs"] --> UI
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Static route declarations
  • ➕ Improves type checking and IDE navigation
  • ➕ Avoids runtime exec for FastAPI handler signatures
  • ➖ Repeats nearly identical CRUD handlers across ten resources
  • ➖ Makes contract-specific parameter names costly to maintain
2. Split by catalog domain
  • ➕ Reduces individual review and rollout risk
  • ➕ Allows domain-specific validation to mature independently
  • ➖ Duplicates cross-stack scaffolding across several PRs
  • ➖ Delays shared UI and service abstractions

Recommendation: Keep the configuration-driven frontend and shared service patterns because the resources have strongly aligned CRUD, pagination, status, and permission behavior. Consider replacing runtime-generated FastAPI handlers with generated or explicit declarations in a follow-up, since static definitions would improve analysis and debugging without abandoning reuse.

Files changed (93) +10144 / -11

Enhancement (33) +4613 / -9
AdminShell.tsxWire catalog sections into the administration shell +63/-1

Wire catalog sections into the administration shell

• Adds permission-aware navigation, route state, page titles, and shared list/form rendering for all catalog resources.

apps/Administration-FE/src/components/AdminShell.tsx

CatalogForm.tsxAdd configuration-driven catalog editor +451/-0

Add configuration-driven catalog editor

• Introduces a reusable create/edit form supporting validation, status transitions, slugs, relationships, rich text, SEO, repeatable images, and media uploads.

apps/Administration-FE/src/components/CatalogForm.tsx

CatalogList.tsxAdd reusable searchable catalog list +230/-0

Add reusable searchable catalog list

• Introduces paginated catalog tables with configurable columns, status and media rendering, relationship details, editing, and confirmed deletion.

apps/Administration-FE/src/components/CatalogList.tsx

FormPageHeader.tsxAdd an accessible back icon to form headers +6/-0

Add an accessible back icon to form headers

• Adds a decorative SVG arrow to improve the visual affordance of form navigation.

apps/Administration-FE/src/components/FormPageHeader.tsx

MediaPreview.tsxPreview uploaded documents by filename +17/-0

Preview uploaded documents by filename

• Recognizes PDF and Word sources and renders a document label instead of attempting an image preview.

apps/Administration-FE/src/components/MediaPreview.tsx

RelationCountCell.tsxAdd accessible relationship-count popovers +115/-0

Add accessible relationship-count popovers

• Displays related item counts with a portal-based, viewport-aware list that closes on outside interaction, scrolling, resizing, or Escape.

apps/Administration-FE/src/components/RelationCountCell.tsx

TableLogo.tsxRender document format badges in media cells +3/-0

Render document format badges in media cells

• Displays PDF, DOC, and DOCX extensions rather than loading document keys as images.

apps/Administration-FE/src/components/TableLogo.tsx

en.jsonAdd English catalog administration copy +358/-1

Add English catalog administration copy

• Defines navigation, permissions, fields, states, validation, pagination, deletion, and action text for all ten catalog sections.

apps/Administration-FE/src/i18n/en.json

admin-api.tsAdd generic catalog CRUD API helpers +53/-0

Add generic catalog CRUD API helpers

• Adds typed pagination plus list-all, get, create, patch, and delete helpers parameterized by catalog path.

apps/Administration-FE/src/lib/admin-api.ts

admin-routes.tsRegister catalog list and form routes +36/-0

Register catalog list and form routes

• Extends administration view types, route parsing, and href generation for the ten new sections.

apps/Administration-FE/src/lib/admin-routes.ts

catalog-sections.tsDefine catalog UI schemas and section registry +302/-0

Define catalog UI schemas and section registry

• Centralizes columns, fields, API paths, routes, relationships, accepted media, and lookup helpers for ten administration resources.

apps/Administration-FE/src/lib/catalog-sections.ts

applications.astroExpose the applications administration route +4/-0

Expose the applications administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/applications.astro

email-configuration.astroExpose the email configuration administration route +4/-0

Expose the email configuration administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/email-configuration.astro

email-templates.astroExpose the email templates administration route +4/-0

Expose the email templates administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/email-templates.astro

employee-testimonials.astroExpose the employee testimonials administration route +4/-0

Expose the employee testimonials administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/employee-testimonials.astro

memberships.astroExpose the memberships administration route +4/-0

Expose the memberships administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/memberships.astro

news-categories.astroExpose the news categories administration route +4/-0

Expose the news categories administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/news-categories.astro

news.astroExpose the news administration route +4/-0

Expose the news administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/news.astro

openings.astroExpose the openings administration route +4/-0

Expose the openings administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/openings.astro

resource-categories.astroExpose the resource categories administration route +4/-0

Expose the resource categories administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/resource-categories.astro

resources.astroExpose the resources administration route +4/-0

Expose the resources administration route

• Adds an Astro entry point that mounts the shared administration application.

apps/Administration-FE/src/pages/admin/resources.astro

admin.cssStyle catalog forms, relationships, and document indicators +136/-4

Style catalog forms, relationships, and document indicators

• Improves responsive form headers and adds styles for relationship popovers, file badges, and document previews.

apps/Administration-FE/src/styles/admin.css

catalog.pyExpose shared admin and public catalog routers +344/-0

Expose shared admin and public catalog routers

• Builds permission-checked CRUD routers and published-only UUID or slug read routers for all ten resources.

apps/Backend/src/flycatch_api/api/catalog.py

main.pyRegister catalog API endpoints +21/-0

Register catalog API endpoints

• Mounts the ten administration routers and ten public routers under the versioned API prefix.

apps/Backend/src/flycatch_api/main.py

__init__.pyExport catalog ORM models +30/-0

Export catalog ORM models

• Makes new catalog entities and relationship models available through the central models package.

apps/Backend/src/flycatch_api/models/init.py

catalog.pyModel catalog entities and associations +299/-0

Model catalog entities and associations

• Defines SQLAlchemy models for applications, openings, testimonials, email settings, news, resources, memberships, and their relationships.

apps/Backend/src/flycatch_api/models/catalog.py

admin_catalog.pyDefine administration catalog schemas +507/-0

Define administration catalog schemas

• Adds strict Pydantic detail, summary, list, and write models with domain constraints, nested relations, SEO, and statuses.

apps/Backend/src/flycatch_api/schemas/admin_catalog.py

public_catalog.pyDefine published catalog response schemas +243/-0

Define published catalog response schemas

• Adds public list and detail models that omit administration state while preserving relevant nested content.

apps/Backend/src/flycatch_api/schemas/public_catalog.py

author_service.pyProtect authors referenced by news +6/-1

Protect authors referenced by news

• Prevents author deletion when either blogs or catalog news records still reference the author.

apps/Backend/src/flycatch_api/services/author_service.py

catalog_service.pyImplement catalog business services +1307/-0

Implement catalog business services

• Implements validation, sanitization, slug uniqueness, search, pagination, relationships, CRUD, and published-only projections across ten domains.

apps/Backend/src/flycatch_api/services/catalog_service.py

media_service.pyAllow bounded PDF and Word uploads +13/-2

Allow bounded PDF and Word uploads

• Extends media validation to PDF, DOC, and DOCX files with a dedicated 10 MB limit.

apps/Backend/src/flycatch_api/services/media_service.py

role_service.pyRegister catalog RBAC resources +10/-0

Register catalog RBAC resources

• Adds all ten catalog resource identifiers to the role permission catalog.

apps/Backend/src/flycatch_api/services/role_service.py

text.pyDerive display formats from document keys +23/-0

Derive display formats from document keys

• Adds a helper that maps common image and document extensions to uppercase format labels.

apps/Backend/src/flycatch_api/services/text.py

Tests (6) +386 / -1
a11y-admin.spec.tsCheck catalog list and form accessibility +20/-0

Check catalog list and form accessibility

• Runs Axe against authenticated applications list and create views and rejects critical WCAG 2.2 AA violations.

apps/Administration-FE/tests/e2e/a11y-admin.spec.ts

admin-catalog.spec.tsVerify catalog navigation and application form access +34/-0

Verify catalog navigation and application form access

• Exercises authenticated navigation to applications, news, and memberships plus opening and canceling the application form.

apps/Administration-FE/tests/e2e/admin-catalog.spec.ts

admin-routes.test.tsTest catalog route parsing and hrefs +14/-0

Test catalog route parsing and hrefs

• Covers all new list routes and representative href generation for catalog sections.

apps/Administration-FE/tests/unit/admin-routes.test.ts

catalog-sections.test.tsTest catalog registry behavior +48/-0

Test catalog registry behavior

• Verifies all ten resources, view mappings, resume formats, and automatic slug field sources.

apps/Administration-FE/tests/unit/catalog-sections.test.ts

test_openapi_parity.pyInclude catalog contracts in API parity checks +21/-1

Include catalog contracts in API parity checks

• Adds all administration and public catalog specifications to OpenAPI path parity validation.

apps/Backend/tests/contract/test_openapi_parity.py

test_admin_catalog.pyCover catalog APIs and document uploads +249/-0

Cover catalog APIs and document uploads

• Tests authentication, CRUD relationships, publish filtering, slugs, nested public payloads, validation, and PDF size enforcement.

apps/Backend/tests/integration/test_admin_catalog.py

Documentation (50) +4906 / -0
admin-applications.v1.yamlDefine the administration applications contract +268/-0

Define the administration applications contract

• Specifies secured application CRUD, search, pagination, validation, status, resume metadata, and error responses.

specs/023-admin-applications/contracts/admin-applications.v1.yaml

public-applications.v1.yamlDefine the public applications contract +119/-0

Define the public applications contract

• Specifies unauthenticated list and detail reads for published application records without administration status.

specs/023-admin-applications/contracts/public-applications.v1.yaml

data-model.mdDocument the application data model +30/-0

Document the application data model

• Describes application fields, opening relationships, resume format derivation, lifecycle, and search behavior.

specs/023-admin-applications/data-model.md

quickstart.mdAdd applications validation quickstart +14/-0

Add applications validation quickstart

• Documents migration and permission prerequisites plus basic administration and public API checks.

specs/023-admin-applications/quickstart.md

spec.mdSpecify application administration and publication +62/-0

Specify application administration and publication

• Defines scope, security, permissions, pagination, resume handling, public filtering, and acceptance scenarios.

specs/023-admin-applications/spec.md

admin-openings.v1.yamlDefine the administration openings contract +294/-0

Define the administration openings contract

• Specifies secured opening CRUD with enumerated job fields, slug behavior, embedded applications, pagination, and errors.

specs/024-admin-openings/contracts/admin-openings.v1.yaml

public-openings.v1.yamlDefine the public openings contract +136/-0

Define the public openings contract

• Specifies published opening lists and slug-based details with embedded application records.

specs/024-admin-openings/contracts/public-openings.v1.yaml

data-model.mdDocument the opening data model +29/-0

Document the opening data model

• Describes job fields, allowed values, application relationships, slug generation, lifecycle, and search.

specs/024-admin-openings/data-model.md

quickstart.mdAdd openings validation quickstart +14/-0

Add openings validation quickstart

• Documents prerequisites and smoke checks for administration CRUD and published public reads.

specs/024-admin-openings/quickstart.md

spec.mdSpecify opening administration and publication +62/-0

Specify opening administration and publication

• Defines permission, pagination, slug, application embedding, public filtering, and acceptance requirements.

specs/024-admin-openings/spec.md

admin-employee-testimonials.v1.yamlDefine the administration testimonials contract +253/-0

Define the administration testimonials contract

• Specifies secured testimonial CRUD, ordering, listing flags, publication dates, pagination, and validation errors.

specs/025-admin-employee-testimonials/contracts/admin-employee-testimonials.v1.yaml

public-employee-testimonials.v1.yamlDefine the public testimonials contract +112/-0

Define the public testimonials contract

• Specifies published testimonial list and UUID detail responses without administration status.

specs/025-admin-employee-testimonials/contracts/public-employee-testimonials.v1.yaml

data-model.mdDocument the employee testimonial model +26/-0

Document the employee testimonial model

• Describes testimonial content, media, ordering, listing, publication lifecycle, and search.

specs/025-admin-employee-testimonials/data-model.md

quickstart.mdAdd testimonials validation quickstart +14/-0

Add testimonials validation quickstart

• Documents prerequisites and basic administration and public endpoint verification.

specs/025-admin-employee-testimonials/quickstart.md

spec.mdSpecify testimonial administration and publication +62/-0

Specify testimonial administration and publication

• Defines permissions, ordering, independent listing status, pagination, filtering, and acceptance criteria.

specs/025-admin-employee-testimonials/spec.md

admin-email-configuration.v1.yamlDefine the administration email configuration contract +245/-0

Define the administration email configuration contract

• Specifies secured CRUD for SMTP addresses with email validation, pagination, status, and errors.

specs/026-admin-email-configuration/contracts/admin-email-configuration.v1.yaml

public-email-configuration.v1.yamlDefine the public email configuration contract +108/-0

Define the public email configuration contract

• Specifies published email configuration list and UUID detail reads.

specs/026-admin-email-configuration/contracts/public-email-configuration.v1.yaml

data-model.mdDocument the email configuration model +22/-0

Document the email configuration model

• Describes required SMTP email fields, publication lifecycle, and search behavior.

specs/026-admin-email-configuration/data-model.md

quickstart.mdAdd email configuration validation quickstart +14/-0

Add email configuration validation quickstart

• Documents migration, permissions, CRUD, publication, and public-read checks.

specs/026-admin-email-configuration/quickstart.md

spec.mdSpecify email configuration administration +61/-0

Specify email configuration administration

• Defines access controls, email validation, pagination, published-only public reads, and acceptance requirements.

specs/026-admin-email-configuration/spec.md

admin-email-templates.v1.yamlDefine the administration email templates contract +253/-0

Define the administration email templates contract

• Specifies secured template CRUD with rich text, unique slugs, template types, statuses, and errors.

specs/027-admin-email-templates/contracts/admin-email-templates.v1.yaml

public-email-templates.v1.yamlDefine the public email templates contract +107/-0

Define the public email templates contract

• Specifies published template lists and slug-based detail reads.

specs/027-admin-email-templates/contracts/public-email-templates.v1.yaml

data-model.mdDocument the email template model +23/-0

Document the email template model

• Describes body, unique slug, template type, subject, lifecycle, and search fields.

specs/027-admin-email-templates/data-model.md

quickstart.mdAdd email templates validation quickstart +14/-0

Add email templates validation quickstart

• Documents prerequisites and core administration and public API smoke tests.

specs/027-admin-email-templates/quickstart.md

spec.mdSpecify email template administration +61/-0

Specify email template administration

• Defines permissions, allowed types, slug uniqueness, publication filtering, pagination, and acceptance requirements.

specs/027-admin-email-templates/spec.md

admin-news-categories.v1.yamlDefine the administration news categories contract +239/-0

Define the administration news categories contract

• Specifies secured named-category CRUD, search, pagination, publication status, and errors.

specs/028-admin-news-categories/contracts/admin-news-categories.v1.yaml

public-news-categories.v1.yamlDefine the public news categories contract +106/-0

Define the public news categories contract

• Specifies published category lists and UUID detail reads.

specs/028-admin-news-categories/contracts/public-news-categories.v1.yaml

data-model.mdDocument the news category model +20/-0

Document the news category model

• Describes category identity, name, status lifecycle, timestamps, and search.

specs/028-admin-news-categories/data-model.md

quickstart.mdAdd news categories validation quickstart +14/-0

Add news categories validation quickstart

• Documents prerequisites and administration-to-public publication checks.

specs/028-admin-news-categories/quickstart.md

spec.mdSpecify news category administration +60/-0

Specify news category administration

• Defines secured CRUD, pagination, published-only reads, and acceptance scenarios.

specs/028-admin-news-categories/spec.md

admin-news.v1.yamlDefine the administration news contract +330/-0

Define the administration news contract

• Specifies secured news CRUD with slugs, rich content, authors, categories, social fields, SEO, and errors.

specs/029-admin-news/contracts/admin-news.v1.yaml

public-news.v1.yamlDefine the public news contract +163/-0

Define the public news contract

• Specifies published news lists and slug details with embedded authors, categories, media, and SEO.

specs/029-admin-news/contracts/public-news.v1.yaml

data-model.mdDocument the news data model +28/-0

Document the news data model

• Describes content, social links, SEO, author and category relationships, lifecycle, and search.

specs/029-admin-news/data-model.md

quickstart.mdAdd news validation quickstart +14/-0

Add news validation quickstart

• Documents prerequisites and smoke checks for secured management and published public reads.

specs/029-admin-news/quickstart.md

spec.mdSpecify news administration and publication +61/-0

Specify news administration and publication

• Defines permissions, relationships, slug generation, SEO reuse, pagination, filtering, and acceptance criteria.

specs/029-admin-news/spec.md

admin-resource-categories.v1.yamlDefine the administration resource categories contract +239/-0

Define the administration resource categories contract

• Specifies secured named-category CRUD, search, pagination, statuses, and errors.

specs/030-admin-resource-categories/contracts/admin-resource-categories.v1.yaml

public-resource-categories.v1.yamlDefine the public resource categories contract +106/-0

Define the public resource categories contract

• Specifies published resource category lists and UUID detail reads.

specs/030-admin-resource-categories/contracts/public-resource-categories.v1.yaml

data-model.mdDocument the resource category model +20/-0

Document the resource category model

• Describes category identity, required name, status lifecycle, timestamps, and search.

specs/030-admin-resource-categories/data-model.md

quickstart.mdAdd resource categories validation quickstart +14/-0

Add resource categories validation quickstart

• Documents migration, permissions, CRUD, publication, and public-read checks.

specs/030-admin-resource-categories/quickstart.md

spec.mdSpecify resource category administration +60/-0

Specify resource category administration

• Defines secured CRUD, pagination, published-only reads, and acceptance requirements.

specs/030-admin-resource-categories/spec.md

admin-resources.v1.yamlDefine the administration resources contract +288/-0

Define the administration resources contract

• Specifies secured resource CRUD with media, PDFs, slugs, categories, SEO, pagination, and validation.

specs/031-admin-resources/contracts/admin-resources.v1.yaml

public-resources.v1.yamlDefine the public resources contract +134/-0

Define the public resources contract

• Specifies published resource lists and slug details with categories, media, documents, and SEO.

specs/031-admin-resources/contracts/public-resources.v1.yaml

data-model.mdDocument the resource data model +26/-0

Document the resource data model

• Describes media, reading time, slug, PDF, SEO, category relationships, lifecycle, and search.

specs/031-admin-resources/data-model.md

quickstart.mdAdd resources validation quickstart +14/-0

Add resources validation quickstart

• Documents prerequisites and core administration and public API checks.

specs/031-admin-resources/quickstart.md

spec.mdSpecify resource administration and publication +61/-0

Specify resource administration and publication

• Defines permissions, slugging, category selection, PDF upload, SEO, pagination, and public filtering.

specs/031-admin-resources/spec.md

admin-memberships.v1.yamlDefine the administration memberships contract +276/-0

Define the administration memberships contract

• Specifies secured membership CRUD with repeatable images, SEO, statuses, pagination, and errors.

specs/032-admin-memberships/contracts/admin-memberships.v1.yaml

public-memberships.v1.yamlDefine the public memberships contract +132/-0

Define the public memberships contract

• Specifies published membership list and UUID detail payloads with images and SEO.

specs/032-admin-memberships/contracts/public-memberships.v1.yaml

data-model.mdDocument the membership data model +23/-0

Document the membership data model

• Describes content, repeatable image JSON, SEO, lifecycle, timestamps, and search.

specs/032-admin-memberships/data-model.md

quickstart.mdAdd memberships validation quickstart +14/-0

Add memberships validation quickstart

• Documents prerequisites and administration-to-public publication checks.

specs/032-admin-memberships/quickstart.md

spec.mdSpecify membership administration and publication +61/-0

Specify membership administration and publication

• Defines permissions, repeatable images, SEO summaries, pagination, published-only reads, and acceptance criteria.

specs/032-admin-memberships/spec.md

Other (4) +239 / -1
check-contract-drift.mjsRequire generated clients for all catalog contracts +10/-0

Require generated clients for all catalog contracts

• Adds the ten new administration contract clients to drift validation so generated artifacts cannot silently fall behind.

apps/Administration-FE/scripts/check-contract-drift.mjs

check-i18n.mjsInclude catalog components in localization checks +4/-1

Include catalog components in localization checks

• Extends literal-string validation to the shared catalog list, form, relation cell, and landing form components.

apps/Administration-FE/scripts/check-i18n.mjs

generate-client.mjsGenerate clients from ten catalog contract sets +29/-0

Generate clients from ten catalog contract sets

• Registers each new administration OpenAPI contract directory and output in the frontend client-generation pipeline.

apps/Administration-FE/scripts/generate-client.mjs

025_catalog_sections.pyCreate catalog tables and relationships +196/-0

Create catalog tables and relationships

• Adds ten entity tables, three many-to-many link tables, status fields, JSON content, slug constraints, and reversible teardown.

apps/Backend/alembic/versions/025_catalog_sections.py

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (7) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Draft applicants leak publicly 🐞 Bug ⛨ Security
Description
A published opening serializes every linked application without checking the application's status,
so draft applicants and their resume key, contact details, compensation, and free-form information
become anonymously readable. This bypasses the public catalog rule that drafts must not appear on
public routes.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R459-460]

+            applications=[
+                public_application(link.application) for link in row.application_links if link.application
Evidence
The opening public serializer maps every relationship through public_application, whose schema
contains resume, contact, compensation, and additional-information fields; only the opening itself
is status-filtered. The applications specification explicitly says drafts must not appear on public
routes.

apps/Backend/src/flycatch_api/services/catalog_service.py[188-204]
apps/Backend/src/flycatch_api/services/catalog_service.py[329-340]
apps/Backend/src/flycatch_api/schemas/public_catalog.py[11-27]
specs/023-admin-applications/spec.md[9-11]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Published openings currently expose every linked application, including drafts and sensitive applicant fields.

## Issue Context
Only applications with `ContentStatus.publish` may be included by a public opening response; preferably minimize the public applicant schema as well.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[447-462]
- apps/Backend/src/flycatch_api/schemas/public_catalog.py[11-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unlisted testimonials remain public 🐞 Bug ≡ Correctness
Description
list_published filters only by row status and therefore returns testimonials whose listed
publish checkbox is false. Administrators cannot actually hide such testimonials from the public
list using the new visibility control.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R601-604]

+    def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmployeeTestimonialList:
+        query = db.query(EmployeeTestimonialRow).filter(EmployeeTestimonialRow.status == ContentStatus.publish)
+        page, per_page, rows, total = _paginate(
+            query.order_by(EmployeeTestimonialRow.sort_order.asc()), page, per_page
Evidence
The public query checks only ContentStatus.publish, while the feature specification identifies
listed as the Publish checkbox independent of row status and the public schema exposes that value.

apps/Backend/src/flycatch_api/services/catalog_service.py[601-608]
specs/025-admin-employee-testimonials/spec.md[46-50]
apps/Backend/src/flycatch_api/schemas/public_catalog.py[64-74]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The public testimonial list includes rows with `listed=false`, despite `listed` being the testimonial Publish checkbox.

## Issue Context
Keep row `status` and `listed` independent, but require both published status and listed visibility for public listing; clarify whether public detail should apply the same visibility rule.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[601-619]
- specs/025-admin-employee-testimonials/spec.md[46-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Testimonial search is ignored 🐞 Bug ≡ Correctness
Description
The public testimonial endpoint accepts and passes q, but
EmployeeTestimonialService.list_published never applies it. Searches return the unfiltered page
and an incorrect unfiltered total.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R601-604]

+    def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmployeeTestimonialList:
+        query = db.query(EmployeeTestimonialRow).filter(EmployeeTestimonialRow.status == ContentStatus.publish)
+        page, per_page, rows, total = _paginate(
+            query.order_by(EmployeeTestimonialRow.sort_order.asc()), page, per_page
Evidence
The shared public route forwards q, and the public contract declares it, but this implementation
immediately paginates a status-only query; the admin implementation demonstrates the missing
predicates.

apps/Backend/src/flycatch_api/api/catalog.py[108-115]
apps/Backend/src/flycatch_api/services/catalog_service.py[569-584]
apps/Backend/src/flycatch_api/services/catalog_service.py[601-608]
specs/025-admin-employee-testimonials/contracts/public-employee-testimonials.v1.yaml[15-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Public testimonial searches ignore the supplied `q` parameter.

## Issue Context
Apply the same appropriate name/designation/review filtering before pagination so both items and total reflect the query.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[601-608]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Email configuration search ignored 🐞 Bug ≡ Correctness
Description
The public email-configuration endpoint accepts q, but EmailConfigurationService.list_published
paginates a status-only query. Every search therefore returns unfiltered records and totals.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R714-716]

+    def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmailConfigurationList:
+        query = db.query(EmailConfigurationRow).filter(EmailConfigurationRow.status == ContentStatus.publish)
+        page, per_page, rows, total = _paginate(query.order_by(EmailConfigurationRow.created_at.desc()), page, per_page)
Evidence
The common route forwards q and the contract declares it, while the service never references q;
its admin counterpart searches all three email fields.

apps/Backend/src/flycatch_api/api/catalog.py[108-115]
apps/Backend/src/flycatch_api/services/catalog_service.py[684-697]
apps/Backend/src/flycatch_api/services/catalog_service.py[714-719]
specs/026-admin-email-configuration/contracts/public-email-configuration.v1.yaml[15-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Public email-configuration searches ignore the supplied `q` parameter.

## Issue Context
Filter the published query by the relevant email fields before pagination.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[714-719]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Email template search ignored 🐞 Bug ≡ Correctness
Description
The public email-template endpoint accepts q, but EmailTemplateService.list_published never
filters by it. Searches return the complete published template set and unfiltered totals.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R807-809]

+    def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmailTemplateList:
+        query = db.query(EmailTemplateRow).filter(EmailTemplateRow.status == ContentStatus.publish)
+        page, per_page, rows, total = _paginate(query.order_by(EmailTemplateRow.slug.asc()), page, per_page)
Evidence
The slug-based public route forwards q, and the contract declares it, but this method only filters
status and orders by slug; the admin method contains the expected search predicates.

apps/Backend/src/flycatch_api/api/catalog.py[149-163]
apps/Backend/src/flycatch_api/services/catalog_service.py[783-805]
apps/Backend/src/flycatch_api/services/catalog_service.py[807-812]
specs/027-admin-email-templates/contracts/public-email-templates.v1.yaml[15-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Public email-template searches ignore the supplied `q` parameter.

## Issue Context
Filter published templates by slug, subject, and/or type before pagination, consistently with the admin search.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[807-812]
- apps/Backend/src/flycatch_api/api/catalog.py[149-163]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View review recommended (2)
6. Membership search is ignored 🐞 Bug ≡ Correctness
Description
The public membership endpoint accepts q, but MembershipService.list_published does not use it.
Searches always return the unfiltered published page and total.
Code

apps/Backend/src/flycatch_api/services/catalog_service.py[R1231-1234]

+    def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicMembershipList:
+        query = db.query(MembershipRow).filter(MembershipRow.status == ContentStatus.publish)
+        page, per_page, rows, total = _paginate(query.order_by(MembershipRow.created_at.desc()), page, per_page)
+        return PublicMembershipList(items=[self._public(row) for row in rows], page=page, per_page=per_page, total=total)
Evidence
The shared route forwards the contracted query parameter, while the public membership implementation
never references q; the admin method searches title and description.

apps/Backend/src/flycatch_api/api/catalog.py[108-115]
apps/Backend/src/flycatch_api/services/catalog_service.py[1209-1229]
apps/Backend/src/flycatch_api/services/catalog_service.py[1231-1234]
specs/032-admin-memberships/contracts/public-memberships.v1.yaml[15-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Public membership searches ignore the supplied `q` parameter.

## Issue Context
Filter published memberships by title and description before pagination, matching the admin search behavior.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[1231-1234]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Read-only users see mutations 🐞 Bug ≡ Correctness
Description
Catalog navigation is granted with only <resource>.read, but every catalog list unconditionally
exposes Add, Edit, and Delete controls and routes into writable forms. Read-only administrators can
therefore enter mutation flows that inevitably fail at the backend permission checks.
Code

apps/Administration-FE/src/components/CatalogList.tsx[R69-71]

+        <h2>{t(`${ns}.title`)}</h2>
+        <button type="button" className="primary" onClick={onAdd}>
+          {t(`${ns}.add`)}
Evidence
The shell renders catalog navigation based on read permission, but passes no action permissions to
either component. The list always renders Add/Edit/Delete and the form always renders save/publish
actions, whereas the API separately enforces create, update, and delete grants.

apps/Administration-FE/src/components/AdminShell.tsx[637-639]
apps/Administration-FE/src/components/AdminShell.tsx[1370-1392]
apps/Administration-FE/src/components/CatalogList.tsx[66-72]
apps/Administration-FE/src/components/CatalogList.tsx[168-181]
apps/Administration-FE/src/components/CatalogForm.tsx[431-445]
apps/Backend/src/flycatch_api/api/catalog.py[44-52]
apps/Backend/src/flycatch_api/api/catalog.py[80-93]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Read-only catalog users are shown create, update, publish, and delete UI they are not authorized to use.

## Issue Context
Pass resource action permissions into catalog list/form components, hide or disable each mutation control, and prevent direct form navigation when the matching grant is absent.

## Fix Focus Areas
- apps/Administration-FE/src/components/CatalogList.tsx[20-71]
- apps/Administration-FE/src/components/CatalogList.tsx[168-181]
- apps/Administration-FE/src/components/CatalogForm.tsx[431-445]
- apps/Administration-FE/src/components/AdminShell.tsx[1370-1392]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +459 to +460
applications=[
public_application(link.application) for link in row.application_links if link.application

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Draft applicants leak publicly 🐞 Bug ⛨ Security

A published opening serializes every linked application without checking the application's status,
so draft applicants and their resume key, contact details, compensation, and free-form information
become anonymously readable. This bypasses the public catalog rule that drafts must not appear on
public routes.
Agent Prompt
## Issue description
Published openings currently expose every linked application, including drafts and sensitive applicant fields.

## Issue Context
Only applications with `ContentStatus.publish` may be included by a public opening response; preferably minimize the public applicant schema as well.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[447-462]
- apps/Backend/src/flycatch_api/schemas/public_catalog.py[11-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +601 to +604
def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmployeeTestimonialList:
query = db.query(EmployeeTestimonialRow).filter(EmployeeTestimonialRow.status == ContentStatus.publish)
page, per_page, rows, total = _paginate(
query.order_by(EmployeeTestimonialRow.sort_order.asc()), page, per_page

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Unlisted testimonials remain public 🐞 Bug ≡ Correctness

list_published filters only by row status and therefore returns testimonials whose listed
publish checkbox is false. Administrators cannot actually hide such testimonials from the public
list using the new visibility control.
Agent Prompt
## Issue description
The public testimonial list includes rows with `listed=false`, despite `listed` being the testimonial Publish checkbox.

## Issue Context
Keep row `status` and `listed` independent, but require both published status and listed visibility for public listing; clarify whether public detail should apply the same visibility rule.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[601-619]
- specs/025-admin-employee-testimonials/spec.md[46-50]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +601 to +604
def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmployeeTestimonialList:
query = db.query(EmployeeTestimonialRow).filter(EmployeeTestimonialRow.status == ContentStatus.publish)
page, per_page, rows, total = _paginate(
query.order_by(EmployeeTestimonialRow.sort_order.asc()), page, per_page

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Testimonial search is ignored 🐞 Bug ≡ Correctness

The public testimonial endpoint accepts and passes q, but
EmployeeTestimonialService.list_published never applies it. Searches return the unfiltered page
and an incorrect unfiltered total.
Agent Prompt
## Issue description
Public testimonial searches ignore the supplied `q` parameter.

## Issue Context
Apply the same appropriate name/designation/review filtering before pagination so both items and total reflect the query.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[601-608]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +714 to +716
def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmailConfigurationList:
query = db.query(EmailConfigurationRow).filter(EmailConfigurationRow.status == ContentStatus.publish)
page, per_page, rows, total = _paginate(query.order_by(EmailConfigurationRow.created_at.desc()), page, per_page)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

4. Email configuration search ignored 🐞 Bug ≡ Correctness

The public email-configuration endpoint accepts q, but EmailConfigurationService.list_published
paginates a status-only query. Every search therefore returns unfiltered records and totals.
Agent Prompt
## Issue description
Public email-configuration searches ignore the supplied `q` parameter.

## Issue Context
Filter the published query by the relevant email fields before pagination.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[714-719]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +807 to +809
def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicEmailTemplateList:
query = db.query(EmailTemplateRow).filter(EmailTemplateRow.status == ContentStatus.publish)
page, per_page, rows, total = _paginate(query.order_by(EmailTemplateRow.slug.asc()), page, per_page)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

5. Email template search ignored 🐞 Bug ≡ Correctness

The public email-template endpoint accepts q, but EmailTemplateService.list_published never
filters by it. Searches return the complete published template set and unfiltered totals.
Agent Prompt
## Issue description
Public email-template searches ignore the supplied `q` parameter.

## Issue Context
Filter published templates by slug, subject, and/or type before pagination, consistently with the admin search.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[807-812]
- apps/Backend/src/flycatch_api/api/catalog.py[149-163]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +1231 to +1234
def list_published(self, db: Session, q: str | None, page: int, per_page: int) -> PublicMembershipList:
query = db.query(MembershipRow).filter(MembershipRow.status == ContentStatus.publish)
page, per_page, rows, total = _paginate(query.order_by(MembershipRow.created_at.desc()), page, per_page)
return PublicMembershipList(items=[self._public(row) for row in rows], page=page, per_page=per_page, total=total)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

6. Membership search is ignored 🐞 Bug ≡ Correctness

The public membership endpoint accepts q, but MembershipService.list_published does not use it.
Searches always return the unfiltered published page and total.
Agent Prompt
## Issue description
Public membership searches ignore the supplied `q` parameter.

## Issue Context
Filter published memberships by title and description before pagination, matching the admin search behavior.

## Fix Focus Areas
- apps/Backend/src/flycatch_api/services/catalog_service.py[1231-1234]
- apps/Backend/src/flycatch_api/api/catalog.py[108-115]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +69 to +71
<h2>{t(`${ns}.title`)}</h2>
<button type="button" className="primary" onClick={onAdd}>
{t(`${ns}.add`)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

7. Read-only users see mutations 🐞 Bug ≡ Correctness

Catalog navigation is granted with only <resource>.read, but every catalog list unconditionally
exposes Add, Edit, and Delete controls and routes into writable forms. Read-only administrators can
therefore enter mutation flows that inevitably fail at the backend permission checks.
Agent Prompt
## Issue description
Read-only catalog users are shown create, update, publish, and delete UI they are not authorized to use.

## Issue Context
Pass resource action permissions into catalog list/form components, hide or disable each mutation control, and prevent direct form navigation when the matching grant is absent.

## Fix Focus Areas
- apps/Administration-FE/src/components/CatalogList.tsx[20-71]
- apps/Administration-FE/src/components/CatalogList.tsx[168-181]
- apps/Administration-FE/src/components/CatalogForm.tsx[431-445]
- apps/Administration-FE/src/components/AdminShell.tsx[1370-1392]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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