# AGENTS.md

## Web Application Development & Deployment Standard

When a user requests development of a web application, follow these rules.

---

# A. Application Product, UI, Security, and Data Standards

These standards apply before deployment work begins. The agent must build the correct, usable, secure application before declaring the task complete.

## A.1 Classify the Application First

Before generating code, identify the application category and apply the relevant standards:

- Admin portal or back-office system
- Public website
- Customer or partner portal
- Internal operational application
- API-only service
- Mobile-oriented web application
- Mixed public and authenticated application

Also identify:

- Primary users and their goals
- Core workflows
- Roles and permissions
- Main data entities
- Sensitive data and security requirements
- Expected dataset size and traffic
- Desktop, tablet, and mobile usage
- Whether real-time behavior is required

Admin-portal requirements are mandatory for dashboards, CRM, ERP, inventory, reporting, management, workflow, and similar authenticated systems. Do not force an admin sidebar onto public websites or API-only services unless requested.

## A.2 Admin Portal Layout Standard

An admin portal MUST provide:

- A persistent left-side navigation on desktop
- Menu groups and nested submenus where appropriate
- A clear active-page state
- A consistent icon library for menu items
- A top header containing the page title or breadcrumb, user profile menu, and logout action
- Consistent page padding, spacing, and page-header layout
- A primary action area on pages that create or manage records

Desktop sidebar behavior:

- Expanded by default unless compact mode is more suitable
- May support icon-only collapsed mode
- Icon-only menu items MUST have tooltips and accessible labels
- Nested menus must remain understandable while collapsed

Mobile sidebar behavior:

- Convert to an off-canvas drawer
- Open using a visible hamburger-menu button
- Close after navigation
- Close when the overlay is selected
- Trap focus while open and restore focus when closed
- Never cover content permanently or require horizontal page scrolling

## A.3 Responsive Design Requirements

Every page MUST be intentionally usable at minimum at:

```text
360px mobile
768px tablet
1024px small desktop
1440px desktop
```

Required behavior:

- Forms become single-column on small screens where appropriate
- Action buttons wrap or collapse into an overflow menu
- Cards resize without clipping content
- Modals fit small screens and allow internal scrolling
- Tap targets remain comfortably usable
- Important actions do not rely only on hover
- Long text, identifiers, filenames, and URLs wrap or truncate safely
- Fixed widths must not break smaller screens
- No page may require unintended horizontal scrolling
- Long or complex modals must remain vertically scrollable on small screens
- Prefer full-screen or near-full-screen modal behavior on mobile when the form is lengthy
- When a form element wraps the modal header, body, and footer, preserve the modal's flex layout so the body remains the scrollable region
- Prefer making the form itself the modal content container rather than nesting a form inside `.modal-content`, when the UI framework expects the header, body, and footer to be direct children
- Modal headers and footers should remain visible while the modal body scrolls when practical
- Verify modal scrolling with dynamic content, virtual keyboards, and repeated form rows on mobile
- Treat phone, tablet, and desktop modal behavior separately rather than using one broad breakpoint for all non-desktop devices
- Full-screen modal behavior should normally be limited to phones; tablets should retain visible outer spacing on all four sides unless the workflow genuinely requires full-screen use
- For tablet modals, apply spacing to the modal container or viewport wrapper so top, bottom, left, and right margins remain consistent even when JavaScript adjusts modal height
- Verify modal layout in both portrait and landscape tablet orientations
- Do not initialize a modal, dropdown, chart, DataTable, or other framework component before its required JavaScript library has loaded
- When page-specific scripts appear before shared framework scripts in the final HTML, defer initialization with `DOMContentLoaded`, `defer`, or an equivalent lifecycle hook
- Use explicit element lookups inside initialization blocks; do not rely on browser-created global variables from element IDs

For data tables on mobile, the agent must deliberately choose one or more of:

- Controlled horizontal scrolling
- Priority columns with less important columns hidden
- Row-to-card transformation
- Expandable row details

The choice must be based on the data and workflow.

## A.4 Visual Design System

Generated applications MUST define reusable design tokens for:

- Primary, secondary, and accent colors
- Success, warning, danger, and information colors
- Neutral color scale
- Surface, text, border, and focus-ring colors
- Typography scale
- Spacing scale
- Border-radius scale
- Shadow scale

Unless the user specifies branding, choose a restrained professional palette appropriate to the application domain.

Design rules:

- Use one dominant primary color
- Use accent colors sparingly
- Prefer neutral surfaces for data-heavy interfaces
- Maintain strong text and control contrast
- Avoid excessive gradients and unrelated colors
- Use semantic status colors consistently
- Never use color as the only status indicator
- Implement default, hover, focus, active, disabled, loading, error, and success states

### A.4.1 Typography and Font Standard

Unless the user or an established brand system specifies another typeface, web applications MUST use **Poppins** as the primary interface font.

Required font stack:

```css
font-family: "Poppins", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
```

Typography rules:

- Apply the primary font globally at the root or body level so all pages inherit it consistently
- Ensure buttons, inputs, selects, textareas, dialogs, tables, navigation, dropdowns, editable regions, and third-party components inherit the same font
- Load only the weights actually used; the recommended application set is 400, 500, 600, 700, and 800
- Use consistent weight semantics: 400 for body text, 500 for supporting emphasis, 600 for controls and section labels, and 700 or 800 for headings
- Define typography sizes, line heights, letter spacing, and weights as reusable design tokens rather than page-specific values
- Do not introduce a second interface font on individual pages or components without an explicit branding or functional reason
- Preserve a dedicated monospace stack for source code, logs, terminal output, identifiers where alignment matters, and keyboard shortcuts
- Provide local or self-hosted font assets when external font delivery is unreliable, restricted, or inappropriate for the deployment environment
- Include suitable fallback fonts so the interface remains usable while the primary font loads or if it fails
- Avoid synthetic bold or italic styles when the required font face can be loaded explicitly
- Verify typography in light and dark themes, at mobile and desktop widths, and inside modals, tables, cards, and form controls

## A.5 Icons

Use one consistent icon library throughout the application, preferably Lucide Icons or an equivalent maintained library.

Rules:

- Do not mix unrelated icon styles
- Use icons for navigation, important actions, status, cards, empty states, and destructive actions where they improve recognition
- Do not use emoji as primary interface icons
- Icon-only buttons MUST have a tooltip and accessible label
- Keep icon size, stroke style, spacing, and alignment consistent
- Do not add decorative icons where they create visual noise

## A.6 Authentication Flow

Authenticated applications MUST implement a real authentication flow, not a decorative login screen or client-side-only boolean.

Minimum requirements:

- Login page
- Secure password handling
- Authenticated session or secure token flow
- Logout
- Protected routes
- Redirect unauthenticated users to login
- Redirect authenticated users away from login when appropriate
- Session-expiration handling
- Invalid-credentials feedback
- Loading state during login
- Return to the originally requested page after successful login when safe
- Dedicated unauthorized or HTTP 403 state
- Password fields on login, registration, password-change, and password-reset forms should include an accessible show/hide password control using a clear eye icon
- The password visibility control must preserve the field value, update its accessible label and pressed state, and remain keyboard accessible
- Use the application's standard icon library for password visibility controls rather than emoji or text-only symbols

Add these when relevant:

- Forgot-password flow
- Password-reset flow
- Change-password page
- First-login password change
- Login throttling or lockout
- Email verification
- Multi-factor authentication
- Secure remember-me behavior

Never store plaintext passwords, hard-code production credentials, or rely on hidden frontend controls as security.

## A.7 Simple RBAC Standard

Use the simplest suitable role-based access control model first:

- User
- Role
- Permission
- User-role assignment
- Role-permission assignment

Use clear permission names such as:

```text
users.view
users.create
users.update
users.delete
roles.view
roles.manage
orders.view
orders.create
orders.update
orders.delete
reports.view
reports.export
```

RBAC rules:

- Deny by default
- Enforce authorization in the backend or API
- Also hide or disable unavailable frontend actions for usability
- Frontend visibility alone is never authorization
- Direct URL access must still be blocked
- Navigation should be permission-aware
- Destructive permissions should be separate from view and edit permissions
- Provide a clear HTTP 403 page
- Seed an initial administrator securely
- Never commit initial production passwords to source control
- Store roles and permissions in the database when the application must support runtime customization; do not keep the permission matrix only in templates or source-code constants
- Keep a stable machine-readable role key separate from the display name
- Refresh or re-resolve the authenticated user's current role and permissions when authorization-sensitive requests are handled, so role edits take effect without requiring stale sessions to expire
- A deactivated user or role must lose access immediately or at the next request according to the documented session strategy
- Protect page routes, API routes, exports, uploads, and AJAX detail endpoints with the same permission model
- Do not infer write permission from role names such as `admin` or `operator`; check explicit permissions
- Prevent administrative lockout by preserving an emergency or Super Admin capability, and document how it is protected
- System roles may be non-deletable, while custom roles may be deleted only when no users are assigned
- Role and permission changes should be audited
- Database migrations and seed scripts must be idempotent and safe to rerun

Suggested initial roles may include Super Admin, Administrator, Operator, and Viewer, but the agent must adapt roles to the application domain.

## A.8 Data Table Standard

Lists expected to grow MUST use server-side processing.

Required capabilities:

- Server-side pagination
- Server-side filtering
- Use one dedicated filter control per meaningful searchable field; do not combine unrelated columns such as code, name, customer, reference, email, or status into a single generic search input
- Multiple populated field filters MUST be combined with logical AND, while matching within one field may use the field-appropriate operator
- A combined free-text search is acceptable only as an optional secondary convenience when dedicated field filters are also available, or when the dataset genuinely has only one meaningful searchable text field
- Server-side sorting
- Total record count
- Filtered record count
- Stable deterministic ordering
- Configurable page size
- Reasonable maximum page size

A request model should conceptually support:

```text
page
pageSize
sortColumn
sortDirection
filters[]
```

Backend rules:

- Whitelist sortable and filterable columns
- Parameterize all database queries
- Never inject client-provided column names directly into SQL
- Use a stable secondary order, usually a unique identifier
- Do not load the entire dataset into memory before pagination
- Add indexes for common sort and filter paths where appropriate
- Validate pagination syntax against the actual database engine, server version, and application driver before deployment
- Parse page offsets and page sizes as integers and clamp them to safe bounds
- If a driver does not reliably support bound parameters in `LIMIT`, `OFFSET`, or equivalent clauses, interpolate only validated integer values and keep all user-controlled filters parameterized
- Never interpolate raw page, sort, filter, or search values into SQL
- Test pagination queries directly against the production-equivalent database driver

The AI must choose a sensible default order from the data semantics. Examples:

- Transactions and audit logs: newest first
- Tasks: priority, due date, then creation date
- Reference data: name or code ascending
- Users: alphabetical or newest first depending on workflow

### A.8.1 Server-Side Table Response Contract

Every server-side table endpoint MUST return a stable JSON contract expected by the selected table component.

For DataTables-compatible endpoints, a successful response must contain:

```json
{
  "draw": 1,
  "recordsTotal": 100,
  "recordsFiltered": 25,
  "data": []
}
```

On failure, the endpoint must still return valid JSON rather than HTML, an empty response, or a framework error page. A DataTables-compatible failure response should contain:

```json
{
  "draw": 1,
  "recordsTotal": 0,
  "recordsFiltered": 0,
  "data": [],
  "error": "Unable to load records."
}
```

Rules:

- Echo a validated draw or request sequence value when the table protocol requires it
- Ensure `recordsTotal >= recordsFiltered`
- Ensure returned rows do not exceed the requested page size
- Never return a login page, redirect page, stack trace, or generic HTML error to an AJAX table request
- Return HTTP 401 JSON for unauthenticated API requests
- Return HTTP 403 JSON for unauthorized API requests
- Use page redirects only for normal browser-page navigation
- Add a user-friendly client-side table error handler, preferably using SweetAlert2 or the application notification system instead of the component's default warning dialog
- Log detailed failures on the server while showing a safe message to users

### A.8.2 Server-Side Table Validation

Before declaring a server-side table complete, test:

- Initial page load
- Second and later pages
- Minimum, default, and maximum page sizes
- Ascending and descending sorting
- Every supported sortable column
- Default sorting
- Empty datasets
- Searches with no matches
- Single and combined filters
- Invalid or unknown sort-column requests
- Negative and excessively large page offsets
- Page requests beyond the final page
- Authentication expiration during an AJAX request

Verify that table requests do not restart or terminate the application process.

## A.9 Table Columns and Headers

Data-table columns MUST be sized according to content importance.

Requirements:

- Headers should not be unnecessarily truncated
- Long values should wrap or truncate with tooltip where appropriate
- Numeric values align right
- Dates use consistent formatting
- Action columns remain compact
- In every DataTable that includes row action buttons, the Actions column MUST be the first column on the left
- The left-side Actions column must be compact, non-sortable, non-searchable, and visually aligned to the left
- Keep row actions in a consistent order, such as View, Edit, then Delete, and provide icons, tooltips, and accessible labels for icon-only buttons
- Every page that contains a DataTable MUST provide a dedicated search/filter card appropriate to that dataset
- DataTable filter cards MUST be collapsible and should be expanded by default unless the user requests otherwise
- Every collapsible search/filter card MUST have a visible trigger button with a filter icon, clear label, `aria-expanded`, and `aria-controls`
- The trigger should visually indicate expanded or collapsed state, such as a rotating chevron
- DataTable filters must use dedicated controls per meaningful field and combine populated fields with logical AND
- Every DataTable MUST provide at least one appropriate row action, such as View, Edit, or Delete, according to the workflow and permissions
- A read-only DataTable should still provide a View or Details action when record-level inspection is meaningful
- Boolean values use readable labels, badges, or icons
- Status values use accessible badges
- Identifiers remain copyable
- Table width must not create unnecessary page overflow
- Sortable headers clearly indicate sorting capability and direction
- Sorting must be keyboard accessible
- Not every column must be sortable

Add when useful:

- Column visibility chooser
- Sticky header
- Empty state
- Loading skeleton
- Error state with retry
- Row-count summary
- Page-size choices such as 10, 25, 50, and 100
- Preservation of list state after visiting detail or edit pages

## A.10 Advanced Filter Section

Data-list pages MUST support multiple filters combined with logical AND between separate fields.

Supported filter controls may include:

- Text input
- Select or dropdown
- Searchable combobox
- Multi-select dropdown
- Checkbox-list dropdown
- Date picker
- Date range
- Numeric range
- Boolean selector
- Status selector
- Related-entity lookup

Required behavior:

- Filter section is collapsible
- Active filters are visually indicated
- Provide Apply Filters and Reset Filters actions
- Applying or resetting filters returns to page 1
- Filters survive pagination and sorting
- Enter applies suitable text filters
- Active filters may appear as removable chips
- Preserve filters in the URL where practical
- Debounce expensive live searches
- Separate filter fields use logical AND
- Multiple selected values inside one field normally use logical OR

Example:

```text
Status IN (Active, Pending)
AND Department = Finance
AND Name contains "Edi"
```

## A.11 CRUD and Form Standards

Admin modules should use consistent patterns:

- List
- Detail where useful
- Create
- Edit
- Delete confirmation
- Archive and restore where permanent deletion is inappropriate

Requirements:

- Client-side and server-side validation
- Required fields clearly identified
- Inline errors near the affected fields
- Preserve submitted values after validation failure
- Confirmation for destructive actions
- Success and error feedback
- Prevent duplicate submission
- Loading state on submit actions
- Warn about unsaved changes where appropriate
- Use a full page instead of a modal for complex forms

### A.11.1 Foreign-Entity Lookup and Search Standard

Whenever a module selects a record from another table through a foreign key, the application MUST provide a searchable, user-friendly lookup instead of relying on a long plain dropdown.

Required behavior:

- Allow searching by the foreign entity's meaningful human identifiers, not only by its numeric ID
- Include the most useful searchable fields for the entity, such as code, SKU, order number, name, email, customer, or reference number
- Display a concise composite label that helps the user distinguish similar records, for example `SKU · Product Name · Stock` or `Order No · Customer · Balance`
- Store and submit the stable foreign-key identifier while displaying human-readable text
- Preserve the selected value when editing an existing record
- Support keyboard navigation, clear selection, focus states, and accessible labels
- When used inside a modal, attach the dropdown to the modal or an appropriate modal container so it is not hidden behind the backdrop and does not break modal scrolling
- Dynamically added form rows MUST initialize the searchable lookup after insertion and clean up the lookup instance before row removal
- Changes in the selected foreign record must continue to trigger dependent calculations, validation, and field updates

Scale and query requirements:

- Small bounded datasets may be rendered as local searchable options
- Large, frequently changing, or permission-sensitive datasets MUST use debounced server-side or AJAX search with pagination and result limits
- Server-side search must use parameterized queries and search only an explicit allowlist of columns
- Combine separate search terms with logical AND where appropriate; a single free-text term may search multiple approved identifying columns with logical OR
- Do not load an unbounded foreign table into the page merely to provide a lookup
- Return only fields required to identify and select the record
- Apply authorization, tenant scoping, active/inactive rules, availability rules, and soft-delete rules to lookup results
- Validate the submitted foreign key again on the server; never trust that a value was valid merely because it appeared in the client selector
- Reject missing, inactive, unauthorized, deleted, or otherwise invalid related records with a clear validation message

Examples:

```text
Product lookup:
Search SKU OR product name
Display SKU · Product Name · Available Stock
Submit product_id

Order lookup:
Search order number OR customer name
Display Order No · Customer · Outstanding Balance
Submit order_id
```

### A.11.2 Image Upload, Preview, and Display Standard

When an entity supports images, the generated application MUST implement a complete image lifecycle rather than only storing a filename.

Upload requirements:

- Support image selection in create and edit forms
- Show an immediate client-side preview before submission
- Display the current stored image on edit and view pages
- Allow users to replace the current image
- Provide an explicit remove-image action when removal is permitted
- Preserve the existing image when an edit form is submitted without a replacement
- Use multipart form handling or an equivalent secure upload mechanism
- Generate safe unique stored filenames rather than trusting the original filename
- Store only the required relative path or media identifier in the database
- Keep uploaded files outside source-controlled directories
- For cookie-authenticated multipart forms, ensure CSRF validation happens after the multipart parser has made form fields available, or require a validated CSRF header that can be checked before parsing
- Do not globally skip CSRF protection for all multipart requests without adding an equivalent route-level check
- If CSRF, validation, authorization, or database persistence fails after a temporary upload has been written, remove the temporary file
- Middleware order for multipart routes should be explicit and reviewed: authentication, authorization, upload limits/parser, multipart CSRF validation, file-content validation, business logic, and compensating cleanup

Validation requirements:

- Validate file type on both client and server
- Validate actual file content or signature on the server; do not trust only the extension or MIME type supplied by the browser
- Use an allowlist such as JPEG, PNG, or WebP unless the user requires another format
- Enforce a configurable maximum upload size
- Reject executable, scriptable, malformed, or unsupported content
- Normalize image orientation when needed
- Prevent path traversal and filename collisions
- Return clear validation messages without exposing internal filesystem paths

Display requirements:

- Use a compact thumbnail in data-table rows when an image column is useful
- Keep row thumbnails consistently sized with `object-fit: cover` or an equivalent strategy
- Make the thumbnail keyboard-accessible and clickable when a larger preview is useful
- Open the larger preview in an accessible modal, lightbox, or SweetAlert2 image dialog
- Display images responsively without distortion
- Provide meaningful alternative text based on the entity when possible
- Show a professional placeholder or fallback state when no image is available
- Do not display full-resolution images directly as small table thumbnails when a generated or cached thumbnail is appropriate

Replacement and deletion requirements:

- Save and validate the replacement before removing the previous image
- Delete orphaned files after a successful replacement or entity deletion when safe
- Do not delete shared media that may still be referenced by other records
- Keep database and filesystem changes consistent; use compensating cleanup when a database operation fails
- Log upload, replacement, and deletion failures

Security and performance requirements:

- Enforce authorization for upload, replacement, removal, and viewing of protected media
- Do not allow uploaded files to execute as server-side code
- Serve public media from a controlled static-media path
- Serve private media through an authorized endpoint or signed-access mechanism
- Set appropriate cache and content-type headers
- Consider thumbnail generation, compression, or resizing for large images
- Avoid blocking the main request thread with expensive image processing when background processing is more suitable

For an image-enabled data table, verify:

```text
[ ] Thumbnail appears in the correct row
[ ] Missing image uses a fallback state
[ ] Clicking or activating the thumbnail opens a larger preview
[ ] Preview works by keyboard and on mobile
[ ] Sorting and filtering do not break image URLs
[ ] Pagination does not cause incorrect image-to-row mapping
```

## A.12 Dashboard Quality

Dashboards must support decisions rather than display decorative metrics.

- Cards should link to relevant detail pages
- Show metric time ranges
- Use appropriate chart types
- Provide loading, empty, and error states
- Avoid misleading visual scales
- Avoid excessive animation
- Avoid pie charts with too many categories
- Use consistent number and currency formatting
- Make charts responsive
- Provide accessible labels or text summaries
- Dashboard analytics must come from real application data and use clearly documented inclusion rules, such as whether cancelled orders are excluded
- Time-series charts should include zero-value periods when missing periods would otherwise create a misleading visual gap
- Separate metrics with different units onto separate axes or charts when combining them would distort interpretation
- Server queries for dashboards should avoid row multiplication from multi-table joins; use pre-aggregation, correlated aggregates, or separate queries where necessary
- Empty chart datasets must render a useful empty state rather than throwing a client-side error

### A.12.1 Reporting, Print, PDF, and Spreadsheet Export Standard

When the application includes business reporting, report filters, summary cards, charts, detail tables, print output, PDF, and spreadsheet exports MUST use the same filtering and aggregation rules.

Reporting requirements:

- Support practical period presets such as today, current week, current month, current quarter, current year, and a custom date range
- Use dedicated filters for meaningful dimensions such as status, customer, product, category, payment method, or location
- Combine separate populated filters with logical AND
- Choose trend granularity from the selected range, such as daily for short ranges, monthly for medium ranges, and yearly for long ranges
- Show the selected period and active filter context in printed and exported output
- Export endpoints must enforce the same report permission as the interactive report page
- Exports must be generated from server-validated filters rather than trusting client-provided totals or rows
- Use one shared server-side filter builder or query specification for screen reports and exports to prevent drift
- Avoid loading unbounded report datasets into memory; define safe export limits, streaming behavior, or background jobs for large reports

Print requirements:

- Build a dedicated print document instead of printing the interactive page layout directly
- Hide navigation, filters, buttons, pagination controls, overlays, and other screen-only UI
- Include a report title, selected range, generation time, summary metrics, charts where useful, and the complete filtered detail table
- Do not print only the currently visible DataTable page when the user expects the complete filtered report
- Use explicit print page size, orientation, and margins
- Use page-break rules so summary sections, charts, and table headers do not overlap or split unpredictably
- Repeat table headers on each printed page
- Give print tables explicit column widths and compact, readable typography
- Right-align numeric and currency columns
- Verify print preview in Chromium-based desktop and mobile browsers where supported

PDF requirements:

- Direct PDF export should have a purpose-built layout rather than being a raw screenshot of the page
- Include summary metrics, selected filters, generation metadata, charts where useful, a paginated detail table, and page numbers
- Chart images captured from transparent canvases must be composited onto a white or explicitly chosen background before JPEG encoding; otherwise transparent pixels may become black
- Prefer PNG when transparency is required; prefer JPEG only after painting a solid background
- Validate and size-limit client-supplied chart image payloads before embedding them
- Treat chart snapshots as presentation data only; calculate totals and table rows again on the server
- Gracefully fall back when a chart image is unavailable or malformed
- Ensure images preserve aspect ratio and fit inside bounded chart frames without cropping labels

Spreadsheet requirements:

- Export machine-readable rows, not screenshots
- Include report title, selected range, summary metrics, stable column headings, date formats, numeric/currency formats, and auto-filters when useful
- Freeze header rows for long workbooks
- Avoid merged cells inside the actual data region
- Sanitize text values that could trigger spreadsheet formula execution when opened

## A.13 Accessibility

Target WCAG 2.2 AA where practical.

Minimum requirements:

- Semantic HTML
- Labels associated with form controls
- Full keyboard navigation
- Visible focus states
- Sufficient color contrast
- Native semantics before ARIA
- Accessible dialogs, drawers, and menus
- Focus trapping and focus restoration
- Screen-reader-friendly validation messages
- Icons are not the only indicator of meaning
- Respect reduced-motion preferences
- Meaningful page titles and heading hierarchy

## A.14 Security Baseline

Every generated application MUST include:

- Server-side input validation
- Output encoding
- Parameterized queries
- CSRF protection for cookie-authenticated forms
- XSS protection
- Secure cookie configuration
- HTTPS-only authentication cookies in production
- Appropriate SameSite policy
- Framework-supported password hashing
- Secrets from environment variables or protected configuration
- No credentials in source control
- Rate limiting for authentication and sensitive endpoints
- Authorization checks on every protected backend operation
- Safe file-upload validation, size limits, and allowlisted file types
- Security headers
- Generic production error responses
- Detailed errors only in logs
- Dependency vulnerability checks where available
- CSRF middleware ordering must account for content type: URL-encoded and JSON bodies may be available globally, while multipart fields usually are not available until the multipart parser runs
- For AJAX downloads or POST-based exports, send the CSRF token in a validated request header
- Do not accept large base64 chart or image payloads without explicit request-size limits, per-image limits, type allowlists, and decode-error handling

Prefer framework-native authentication and authorization. Never implement custom cryptography.

## A.15 Audit Logging

Important administrative operations should record:

- Actor user ID
- Action
- Entity type
- Entity ID
- Timestamp
- Relevant before and after values where safe
- IP address where appropriate
- Request or correlation ID

At minimum, audit:

- Login successes and failures
- User, role, and permission changes
- Deletions
- Important status changes
- Sensitive exports
- Security-setting changes

Audit records should be append-oriented and not editable by ordinary administrators.

## A.16 API, Backend, and Data Conventions

Use:

- Correct HTTP status codes
- Consistent response and validation-error structures
- Centralized exception handling
- Structured logging
- Correlation or request IDs
- Database transactions for multi-step mutations
- Idempotency where retries are likely
- Concurrency protection for important edits
- UTC storage for timestamps
- Explicit timezone conversion for display
- DTOs or view models instead of exposing persistence entities directly
- Cancellation and timeout handling
- Protection against N+1 queries

### A.16.1 Async Request Safety

Every asynchronous request handler must propagate failures to centralized error handling.

Requirements:

- Do not leave rejected promises unhandled
- Use the framework's supported async error behavior or a tested async-handler wrapper
- A failed API or database request must not terminate or restart the application process
- Centralized error middleware must distinguish page requests from JSON/API requests
- API errors must return JSON with the correct HTTP status
- Page errors may render an error page
- Table endpoints must preserve their required response contract on failure
- Background tasks and event handlers must also capture and log asynchronous failures

For Express versions that do not automatically forward rejected promises, use a reusable pattern equivalent to:

```js
const asyncRoute = handler =>
  (req, res, next) =>
    Promise.resolve(handler(req, res, next)).catch(next);
```

### A.16.2 Error-Handler Resilience

The error-handling path must remain functional when other parts of the application are failing.

- Error handlers must not require an authenticated user
- Error handlers must not depend on database availability unless unavoidable
- Public and authenticated pages should use separate layouts where appropriate
- Login, HTTP 401, HTTP 403, and public HTTP 404 pages must not assume `user` or session profile data exists
- Shared layouts must safely handle nullable user context
- Error rendering must not trigger another error
- Generic production responses must not expose stack traces, SQL, filesystem paths, secrets, or internal configuration

### A.16.3 Authentication Behavior by Request Type

Authentication and authorization middleware must respond according to the request type:

```text
Normal page request, unauthenticated: redirect to login
API request, unauthenticated: HTTP 401 JSON
Normal page request, unauthorized: HTTP 403 page
API request, unauthorized: HTTP 403 JSON
```

Do not allow AJAX clients, tables, or API consumers to receive a login-page HTML response in place of JSON.

## A.17 URL and State Behavior

For administrative list pages:

- Preserve page, sort, and filters in the URL where practical
- Browser back and forward must work naturally
- Refreshing should preserve useful list context
- Returning from detail or edit should restore prior list state
- Authorized deep links should work

## A.18 Required UI States

Every data-driven page MUST intentionally support:

- Initial loading
- Refresh loading
- Empty dataset
- No matching search results
- API or network error
- Unauthorized
- Forbidden
- Not found
- Partial-data failure where applicable

Never leave a blank screen or expose a raw stack trace.

## A.19 Notifications and Feedback

Use a consistent feedback model:

- Toasts for lightweight success feedback
- Inline messages for form errors
- Dialogs for important confirmations
- Persistent banners for system-wide problems
- Progress indicators for long-running actions

Use SweetAlert2, or a framework-native wrapper around SweetAlert2, for interactive alerts and confirmations when a custom dialog is appropriate.

Rules:

- Do not use native browser `alert()`, `confirm()`, or `prompt()` in the finished application
- Use SweetAlert2 for destructive confirmations, important warnings, session-expiration notices, and image previews where suitable
- Use toast mode for lightweight success or informational feedback
- Use clear confirm and cancel labels that describe the action
- Apply danger styling to destructive confirmations
- Keep focus management and keyboard behavior enabled
- Do not show a success dialog before the server operation has actually succeeded
- Prevent duplicate actions while a confirmation-triggered request is running
- Display useful server validation or failure messages without exposing stack traces
- Prefer inline validation over modal alerts for ordinary field-level errors
- Keep SweetAlert2 theming consistent with the application's design tokens and dark/light appearance

Messages should be specific, for example:

```text
User "Andi" was deactivated successfully.
```

Avoid vague messages such as only `Success` or `Error`.

## A.20 Internationalization and Formatting

- Centralize date, number, currency, and timezone formatting
- Store timestamps in UTC
- Display dates in the configured locale and timezone
- Keep UI strings centralized where practical
- Support long translated labels without breaking layout
- For Indonesian applications, `id-ID` may be the default locale unless specified otherwise

## A.21 Testing Requirements

Before the application is considered complete, verify:

- Authentication flow
- Authorization and RBAC
- Validation
- Server-side pagination
- Filtering and sorting
- CRUD happy paths
- Unauthorized direct access
- Responsive layouts at the required widths
- Basic accessibility
- Health endpoint
- Production build and startup
- Actual database-driver pagination behavior
- API response content type and schema
- Error-handler behavior while unauthenticated
- Session expiry during AJAX and API requests
- Process stability after failed requests

Use automated integration tests for critical business and authorization logic where practical.

### A.21.1 Authenticated End-to-End Smoke Test

For authenticated administrative applications, perform an end-to-end smoke test using the deployed or production-equivalent configuration:

1. Load the login page.
2. Confirm required scripts, icons, styles, and CSRF values are present.
3. Submit valid credentials.
4. Confirm the authenticated session and dashboard load.
5. Open each primary module.
6. Call each server-side table endpoint with realistic pagination, sorting, and filters.
7. Exercise at least one create and edit workflow.
8. Exercise file upload when supported.
9. Exercise one related-record workflow involving foreign keys.
10. Confirm unauthorized access behavior.
11. Inspect fresh application and proxy logs.
12. Verify that the application process remained running without unexpected restart.
- After changing server code, templates, middleware, route registration, environment-dependent behavior, or bundled frontend assets, restart or reload the managed application process before declaring the change complete
- After frontend JavaScript or CSS changes, update the asset version or content hash so browsers do not continue using stale files
- Post-change verification must include process status, health endpoint, relevant application error log, and at least one request exercising the changed path

Use disposable test records and clean them up safely after validation.

### A.21.2 Fresh-Log and Process Validation

Do not rely only on a single `RUNNING` status result.

- Record the process start time, uptime, PID, restart count, or equivalent before smoke testing
- Run the smoke tests
- Check the process information again afterward
- Detect crash loops and unexpected restarts
- Inspect only log entries generated during or after the current validation run
- Preserve existing production logs; use timestamps, line offsets, or log rotation rather than blindly deleting them
- Do not declare success when fresh error entries appear

For Supervisor-managed applications, validation should include the equivalent of:

```text
supervisorctl status <appname>
application error-log inspection
application output-log inspection
```

### A.21.3 Dependency Installation Review

After installing or updating dependencies:

- Review installation output for deprecations, unsupported packages, and security warnings
- Prefer maintained stable major versions
- Resolve security-related warnings when a compatible maintained release exists
- Confirm upgraded package APIs remain compatible with the application
- Commit or preserve the appropriate lockfile
- Run the ecosystem's vulnerability audit where available
- Rebuild and rerun smoke tests after dependency upgrades

### A.21.4 Standalone Page Asset Validation

Standalone pages such as login, password reset, public error pages, and invitation pages must independently load the assets they use.

- Do not assume assets from the authenticated application layout are present
- Verify icons render on every standalone page
- Verify password visibility controls work after icon replacement or DOM updates
- Verify JavaScript failures on standalone pages do not block form submission
- Verify the page remains usable if a non-critical external asset fails to load

## A.22 Seed and Demonstration Data

Development seed data may be used to demonstrate realistic workflows, but:

- Do not use real personal data
- Do not use production default passwords
- Control production seeding explicitly
- Seed the first administrator securely
- Include enough records to demonstrate pagination, filtering, statuses, and permissions

## A.23 Reusable Components

Prefer reusable components for:

- Page headers
- Buttons
- Form controls
- Validation messages
- Data tables
- Filter panels
- Pagination
- Status badges
- Confirmation dialogs
- Empty states
- Loading indicators
- Permission guards

Avoid copying slightly different implementations across pages.

## A.24 Professional Output Rules

Final generated applications must not contain:

- Lorem ipsum or unfinished placeholder copy
- Broken links
- Buttons that do nothing
- Fake charts disconnected from real data
- Hard-coded totals that conflict with stored data
- Inconsistent terminology
- Debug controls
- Raw stack traces
- Default framework branding
- Excessive animation
- Emoji used as primary UI icons

## A.25 Admin Application Definition of Done

Use this checklist before reporting an admin application complete:

```text
[ ] Application type and users identified
[ ] Responsive admin shell implemented
[ ] Desktop sidebar supports menus and submenus
[ ] Mobile sidebar uses accessible hamburger-triggered drawer
[ ] Consistent icon library used
[ ] Authentication flow is functional
[ ] Protected routes are enforced
[ ] Backend authorization is enforced
[ ] Basic RBAC is implemented
[ ] Unauthorized and forbidden states are implemented
[ ] CRUD validation works on client and server
[ ] Image-enabled entities support secure upload, edit preview, replacement, removal, and fallback display
[ ] Image columns use consistent thumbnails and accessible larger previews
[ ] Large data lists use server-side pagination
[ ] Server-side sorting is implemented securely
[ ] Default sorting is semantically appropriate
[ ] Server-side table JSON responses match the component contract
[ ] Table endpoints were tested with pagination, sorting, filters, empty results, and invalid requests
[ ] API authentication failures return JSON rather than login-page HTML
[ ] Multi-filter search uses AND between fields
[ ] Filter panel is collapsible
[ ] Table state survives pagination and sorting
[ ] Mobile table behavior is intentional
[ ] Loading, empty, error, and no-result states exist
[ ] Destructive actions require confirmation
[ ] SweetAlert2 is used instead of native browser alert, confirm, and prompt dialogs
[ ] Audit logging exists for sensitive operations
[ ] Accessibility baseline is met
[ ] No secrets are committed
[ ] Responsive behavior verified at required widths
[ ] Production build succeeds
[ ] Core workflows have been tested
[ ] Async request failures do not crash or restart the application
[ ] Error pages work without an authenticated user
[ ] Fresh logs were inspected after authenticated smoke testing
[ ] Process uptime or restart state was verified after testing
[ ] Dependency deprecation and security warnings were reviewed
```

## A.26 AGENTS.md Backup Iteration Rule

Before modifying `/home/AGENTS.md`:

1. Search for existing files matching `/home/AGENTS.md.bak*`.
2. Find the smallest unused positive integer.
3. Copy the current `/home/AGENTS.md` to `/home/AGENTS.md.bakN`.
4. Never overwrite an existing backup.
5. Verify the backup exists before modifying the original.
6. After editing, read the updated file again and verify completeness.

Example:

```text
Existing: /home/AGENTS.md.bak1
Existing: /home/AGENTS.md.bak2
Create:   /home/AGENTS.md.bak3
```

---

# 1. Supported Technology Stack

Unless explicitly specified otherwise by the user, use one of:

- ASP.NET Core Razor Pages
- Node.js Express.js

Choose the most suitable stack based on requirements.

---

# 2. Application Directory Structure

All applications MUST be stored under:

```text
/home/<appname>
```

Example:

```text
/home/crm
/home/inventory
/home/helpdesk
/home/aiportal
```

The application name must:

- Use lowercase
- Use only letters, numbers, and hyphens
- Be suitable for use as a subdomain
- Match the final subdomain name exactly

Example:

```text
appname: crm
subdomain: crm.sentralogic.id
```

---

# 3. Port Assignment

Each application must run on its own dedicated port.

Before assigning a port:

1. Check currently active listening ports.
2. Check existing Supervisor configurations.
3. Check existing Nginx `proxy_pass` entries.
4. Select an unused port.

Preferred application port range:

```text
5000-5999
```

Examples:

```text
crm       -> 5001
inventory -> 5002
helpdesk  -> 5003
```

Never use a port already assigned to another application.

Recommended checks:

```bash
ss -tulpn
netstat -tulpn
supervisorctl status
grep -R "proxy_pass" /etc/nginx/sites-enabled /etc/nginx/sites-available /etc/nginx/conf.d
```

After starting the application, verify the selected port is listening:

```bash
ss -tulpn | grep <port>
```

The application must listen on either:

```text
127.0.0.1:<port>
```

or:

```text
0.0.0.0:<port>
```

Do not continue to Nginx setup until the application port is confirmed listening.

---

# 4. Required Health Endpoint

Every application MUST provide a health endpoint:

```text
/health
```

Expected response:

```json
{
  "status": "ok"
}
```

The endpoint must return HTTP 200.

Before configuring Nginx or Certbot, verify locally:

```bash
curl -i http://127.0.0.1:<port>/health
```

Deployment is not valid if `/health` does not return HTTP 200.

---

# 5. Application Build & Publish

## ASP.NET Core

For ASP.NET Core web applications, the project SDK MUST be:

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
```

Do not use this for a web application:

```xml
<Project Sdk="Microsoft.NET.Sdk">
```

Publish application into:

```text
/home/<appname>/publish
```

Example:

```bash
dotnet publish -c Release -o /home/crm/publish
```

Application startup command:

```bash
dotnet /home/crm/publish/<assembly>.dll
```

Important:

- Always run the published Release output.
- Do not run stale binaries from `bin/Debug`.
- Do not declare deployment complete based only on successful build.
- Verify the published application starts successfully.

Recommended ASP.NET environment variables:

```text
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://127.0.0.1:<port>
```

---

## Node.js Express

Install dependencies:

```bash
npm install
```

Production startup:

```bash
node server.js
```

or:

```bash
npm start
```

depending on project configuration.

Node.js applications must:

- Define the selected port clearly.
- Prefer reading `PORT` from environment variable.
- Provide `/health` endpoint.
- Have a valid production start command.

Example Express port handling:

```js
const port = process.env.PORT || 5001;
app.listen(port, '127.0.0.1', () => {
  console.log(`App listening on ${port}`);
});
```

---

# 6. Local Application Validation Before Nginx

Before creating or enabling Nginx configuration, validate the application locally.

Required checks:

```bash
curl -i http://127.0.0.1:<port>
curl -i http://127.0.0.1:<port>/health
```

Both must return a successful HTTP response.

If local validation fails:

1. Do not continue to Nginx.
2. Check Supervisor status.
3. Check application logs.
4. Check whether the selected port is listening.
5. Fix the application startup problem first.

---

# 7. Supervisor Configuration

After development is complete, create a Supervisor configuration.

Location:

```text
/etc/supervisor/conf.d/<appname>.conf
```

Example for ASP.NET Core:

```ini
[program:crm]
directory=/home/crm
command=dotnet /home/crm/publish/crm.dll
autostart=true
autorestart=true
stderr_logfile=/var/log/crm.err.log
stdout_logfile=/var/log/crm.out.log
user=root
environment=ASPNETCORE_ENVIRONMENT=Production,ASPNETCORE_URLS=http://127.0.0.1:5001
```

Example for Node.js:

```ini
[program:inventory]
directory=/home/inventory
command=npm start
autostart=true
autorestart=true
stderr_logfile=/var/log/inventory.err.log
stdout_logfile=/var/log/inventory.out.log
user=root
environment=NODE_ENV=production,PORT=5002
```

After creating Supervisor config:

```bash
supervisorctl reread
supervisorctl update
supervisorctl start <appname>
```

Verify:

```bash
supervisorctl status <appname>
```

Status must be:

```text
RUNNING
```

Also check logs:

```bash
tail -n 100 /var/log/<appname>.out.log
tail -n 100 /var/log/<appname>.err.log
```

If startup errors or unhandled exceptions appear in logs, deployment is not complete.

---

# 8. Nginx Reverse Proxy

Create Nginx site configuration.

Location:

```text
/etc/nginx/sites-available/<appname>
```

Example:

```nginx
server {
    listen 80;
    server_name crm.sentralogic.id;

    location / {
        proxy_pass http://127.0.0.1:5001;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

The `proxy_pass` port must exactly match the port where the application is actually listening.

Enable site:

```bash
ln -s /etc/nginx/sites-available/<appname> \
      /etc/nginx/sites-enabled/<appname>
```

If the symlink already exists, verify it points to the correct file.

Validate:

```bash
nginx -t
```

Reload:

```bash
systemctl reload nginx
```

Do not reload Nginx if `nginx -t` fails.

---

# 9. Subdomain Convention

Each application must use:

```text
<appname>.sentralogic.id
```

Examples:

```text
crm.sentralogic.id
inventory.sentralogic.id
helpdesk.sentralogic.id
aiportal.sentralogic.id
```

The application name and subdomain name must match.

---

# 10. DNS Verification

Before requesting SSL, verify DNS record exists:

```text
<appname>.sentralogic.id
```

It must resolve to the server IP.

Check using:

```bash
dig <appname>.sentralogic.id
```

or:

```bash
nslookup <appname>.sentralogic.id
```

Do not proceed with Certbot until DNS is valid.

---

# 11. SSL Certificate

After Nginx is working over HTTP, run:

```bash
certbot --nginx -d <appname>.sentralogic.id
```

Example:

```bash
certbot --nginx -d crm.sentralogic.id
```

Verify HTTPS:

```bash
curl -i https://<appname>.sentralogic.id
curl -i https://<appname>.sentralogic.id/health
```

Both must load correctly.

---

# 12. 502 / 504 Bad Gateway Troubleshooting

If the public URL returns:

```text
502 Bad Gateway
504 Gateway Timeout
```

Do not declare deployment successful.

Immediately check:

1. Supervisor status:

   ```bash
   supervisorctl status <appname>
   ```

2. Application logs:

   ```bash
   tail -n 100 /var/log/<appname>.out.log
   tail -n 100 /var/log/<appname>.err.log
   ```

3. Listening port:

   ```bash
   ss -tulpn | grep <port>
   ```

4. Nginx proxy port:

   ```bash
   grep -R "proxy_pass" /etc/nginx/sites-enabled/<appname> /etc/nginx/sites-available/<appname>
   ```

5. Local health endpoint:

   ```bash
   curl -i http://127.0.0.1:<port>/health
   ```

6. Nginx error log:

   ```bash
   tail -n 100 /var/log/nginx/error.log
   ```

Common causes:

- Application is not running.
- Supervisor config points to the wrong command.
- Nginx `proxy_pass` points to the wrong port.
- Application listens on a different port.
- Application crashed after startup.
- Published output is stale or incorrect.
- ASP.NET project uses the wrong SDK.

Fix the root cause, then re-run all validation checks.

---

# 13. Post Deployment Validation

The deployment is considered complete only when all checks pass.

Verify:

- Application source exists in `/home/<appname>`
- Application build succeeded
- Application publish succeeded
- Application process is running
- Selected port is listening
- Supervisor status is `RUNNING`
- Local HTTP endpoint works
- Local `/health` endpoint works
- Nginx configuration is valid
- Nginx has been reloaded successfully
- DNS resolves correctly
- SSL certificate is installed
- HTTP redirects to HTTPS
- HTTPS endpoint is accessible
- HTTPS `/health` endpoint is accessible
- No startup errors appear in logs
- No 502 or 504 response appears from public URL

Recommended commands:

```bash
supervisorctl status <appname>
ss -tulpn | grep <port>
curl -i http://127.0.0.1:<port>
curl -i http://127.0.0.1:<port>/health
nginx -t
curl -I http://<appname>.sentralogic.id
curl -i https://<appname>.sentralogic.id
curl -i https://<appname>.sentralogic.id/health
tail -n 100 /var/log/<appname>.out.log
tail -n 100 /var/log/<appname>.err.log
```

---

# 14. Required Final Validation

Before declaring deployment successful:

1. Open or request:

   ```text
   https://<appname>.sentralogic.id
   ```

2. Verify HTTP redirects to HTTPS.

3. Verify application responds successfully.

4. Verify `/health` returns HTTP 200 through HTTPS.

5. Verify Supervisor auto-start works.

6. Verify Nginx reloads without errors.

7. Verify SSL certificate is active.

8. Verify logs do not contain startup exceptions.

Only after all checks pass may the deployment be considered complete.

---

# 15. Deployment Success Checklist

Use this checklist before reporting success:

```text
[ ] App name is lowercase and subdomain-safe
[ ] App source created under /home/<appname>
[ ] Correct stack selected
[ ] ASP.NET web app uses Microsoft.NET.Sdk.Web, if applicable
[ ] Dependencies installed
[ ] Build successful
[ ] Publish successful, if applicable
[ ] Unused port selected
[ ] Supervisor config created
[ ] Supervisor reread/update completed
[ ] Supervisor status is RUNNING
[ ] App port is listening
[ ] Local homepage responds
[ ] Local /health responds with HTTP 200
[ ] Nginx site created
[ ] Nginx proxy_pass points to correct port
[ ] Nginx site enabled
[ ] nginx -t passed
[ ] Nginx reloaded successfully
[ ] DNS resolves to server
[ ] Certbot completed successfully
[ ] HTTP redirects to HTTPS
[ ] HTTPS homepage responds
[ ] HTTPS /health responds with HTTP 200
[ ] Logs checked
[ ] No 502/504 errors
[ ] Final public URL confirmed accessible
```

If any item fails, the task is not finished.

---

# 16. Agent Responsibilities

When developing a web application:

1. Create application under:

   ```text
   /home/<appname>
   ```

2. Build application.

3. Publish application for production, if applicable.

4. Select unused port.

5. Add `/health` endpoint.

6. Configure Supervisor.

7. Start Supervisor service.

8. Verify Supervisor is `RUNNING`.

9. Verify port is listening.

10. Verify local HTTP and `/health` endpoints.

11. Configure Nginx reverse proxy.

12. Enable site.

13. Validate and reload Nginx.

14. Verify DNS.

15. Run Certbot.

16. Verify HTTPS homepage.

17. Verify HTTPS `/health` endpoint.

18. Check logs for errors.

19. Confirm application is accessible at:

    ```text
    https://<appname>.sentralogic.id
    ```

The task is not finished until the application is accessible through the HTTPS subdomain and all validation checks pass.
