Establishes the framework's foundation as a multi-site adoptable platform. ADRs (migrations/adr/): - ADR-001 (ACCEPTED): Asset is the platform contract; Machine retires. Three relationship types (partof, controls, connectedto) with free-text label, position-resolution chain (asset > related > location), hierarchical locations, sibling-bay propagation. - ADR-002 (ACCEPTED): Plugin contract semver via __contract_version__. - ADR-003 (ACCEPTED): Hybrid plugin distribution (in-tree bundled + filesystem-based external). - ADR-004 (ACCEPTED): Per-site instances, not multi-tenant. - ADR-005 (ACCEPTED): Equipment plugin (manufacturing) split from measuringtools plugin (metrology). Subtype-table pattern for protocol data (FOCAS, CLM, MTConnect). - ADR-006 (ACCEPTED): Plugin collector contract via get_collector_schema hook with API-key auth and identity-based upsert. Naming convention v1 (CONTRIBUTING.md): - DB tables/columns: lowercase concatenated, no underscores or dashes - DB-mirrored Python/JS variables match column names exactly; pure code follows host-language convention (PEP 8 / camelCase) - Closed acronym allowlist (universal + shop-floor domain), banned shorthand list with suffix exception (printers_bp etc allowed) - Plain ASCII everywhere: chat, docs, comments, string literals Style enforcement (scripts/check-naming-and-style.sh): - Pre-commit-runnable check script: non-ASCII, banned shorthand, snake_case DB names, snake_case API params in frontend - Fixes 14 violations across 11 files (Unicode arrows, snake_case params, ctx -> canvasContext, res -> response, req -> request_obj) Project state (CLAUDE.md, README.md, frontend/CLAUDE.md): - De-staled CLAUDE.md to reflect actual current state - README unifies DB story (MySQL canonical, SQLite test-only) - frontend/CLAUDE.md points at root convention Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
121 lines
4.5 KiB
Markdown
121 lines
4.5 KiB
Markdown
# Frontend Development Standards
|
|
|
|
## Naming Convention (LOCKED)
|
|
|
|
The shopdb-flask naming convention lives in the root `CONTRIBUTING.md`. Read it before naming any variable, component, API param, or CSS class.
|
|
|
|
Frontend-specific reminders pulled from the convention:
|
|
|
|
- Variables holding API field values: match the API field name exactly. Do NOT convert to camelCase. (`response.machineid`, NOT `response.machineId`)
|
|
- Pure JS variables: camelCase (`currentUser`, `isLoading`)
|
|
- Vue components: PascalCase, spelled out (`AssetDetail.vue`, `MachineForm.vue`)
|
|
- CSS classes: lowercase with dashes (`asset-detail`, `machine-form`)
|
|
- API params sent to backend: match DB column names without underscores (`params.locationid = 5`, NOT `params.location_id`)
|
|
- No emojis, em-dashes, smart quotes, or Unicode arrows anywhere. Plain ASCII only.
|
|
- Banned shorthand as standalone variables: `cfg`, `ctx`, `mgr`, `req`, `res`, `env`, `util`, `helper`. Spell them out (`canvasContext`, `response`, `manager`, etc.). Suffix usage like `printers_bp` is allowed.
|
|
|
|
Pre-commit hook at `scripts/check-naming-and-style.sh` enforces these rules.
|
|
|
|
## CSS Styling Standards
|
|
|
|
### Use CSS Variables for ALL Colors
|
|
|
|
**NEVER hardcode colors in component styles.** Always use CSS variables defined in `src/assets/style.css`.
|
|
|
|
Available variables:
|
|
```css
|
|
--primary /* Primary brand color */
|
|
--primary-dark /* Darker primary for hover states */
|
|
--secondary /* Secondary/muted color */
|
|
--success /* Success states (green) */
|
|
--warning /* Warning states (orange) */
|
|
--danger /* Error/danger states (red) */
|
|
--bg /* Page background */
|
|
--bg-card /* Card/panel background */
|
|
--text /* Primary text color */
|
|
--text-light /* Secondary/muted text */
|
|
--border /* Border color */
|
|
--link /* Link color (bright blue in dark mode) */
|
|
```
|
|
|
|
**Bad:**
|
|
```css
|
|
.my-card {
|
|
background: white;
|
|
color: #1a1a1a;
|
|
}
|
|
```
|
|
|
|
**Good:**
|
|
```css
|
|
.my-card {
|
|
background: var(--bg-card);
|
|
color: var(--text);
|
|
}
|
|
```
|
|
|
|
### Detail Pages - Use Global Styles
|
|
|
|
All detail pages (MachineDetail, PCDetail, PrinterDetail, ApplicationDetail) should use the **unified global styles** from `style.css`:
|
|
|
|
- `.detail-page` - Container wrapper
|
|
- `.hero-card` - Main hero section with image and info
|
|
- `.hero-image`, `.hero-content`, `.hero-title`, `.hero-meta`, `.hero-details`
|
|
- `.section-card` - Info sections
|
|
- `.section-title` - Section headers
|
|
- `.info-list`, `.info-row`, `.info-label`, `.info-value`
|
|
- `.content-grid`, `.content-column` - Two-column layout
|
|
- `.audit-footer` - Created/modified timestamps
|
|
|
|
**Only add scoped styles for page-specific elements** (e.g., supplies grid for printers, version list for applications).
|
|
|
|
### PrinterDetail.vue is the Master Template for Detail Pages
|
|
|
|
Use `PrinterDetail.vue` as the reference for new detail pages. Follow its structure and styling patterns.
|
|
|
|
### List Pages - Use Global Styles
|
|
|
|
All list pages should use the **unified global styles** from `style.css`:
|
|
|
|
- `.page-header` - Header with title and action button
|
|
- `.filters` - Search and filter controls
|
|
- `.card` - Main content container
|
|
- `.table-container` - Scrollable table wrapper
|
|
- `table`, `th`, `td` - Table styling
|
|
- `.pagination` - Page navigation
|
|
- `.badge`, `.badge-success`, etc. - Status badges
|
|
- `.actions` - Action button column
|
|
|
|
**PrintersList.vue is the Master Template for List Pages**
|
|
|
|
Use `PrintersList.vue` as the reference for new list pages. It has NO scoped styles - everything uses global CSS.
|
|
|
|
**Only add scoped styles for page-specific elements** (e.g., icon cells for applications, stats badge for knowledge base).
|
|
|
|
### Dark Mode Support
|
|
|
|
Dark mode is automatic via `@media (prefers-color-scheme: dark)`. Using CSS variables ensures colors adapt automatically - no extra work needed per page.
|
|
|
|
## Component Organization
|
|
|
|
- **Global styles**: `src/assets/style.css`
|
|
- **Page-specific styles**: Scoped `<style scoped>` block, only for unique elements
|
|
- **Font sizes**: Use `rem` units, base is 18px for readability on 1080p
|
|
|
|
## File Structure
|
|
|
|
```
|
|
src/
|
|
assets/
|
|
style.css # Global styles, CSS variables, detail page styles
|
|
views/
|
|
machines/
|
|
MachineDetail.vue # Uses global styles only
|
|
pcs/
|
|
PCDetail.vue # Global + PC-specific (app-list, etc.)
|
|
printers/
|
|
PrinterDetail.vue # Global + printer-specific (supplies-grid)
|
|
applications/
|
|
ApplicationDetail.vue # Global + app-specific (version-list, pc-list)
|
|
```
|