From febbd4054a8e959aa61b4b1de8bb0e7ab340e527 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Mon, 14 Apr 2025 12:37:37 +0000 Subject: [PATCH] docs: Update README-context.md with Vue development guidelines - Add Pinia state management documentation - Add comprehensive Vue Facing Decorators guidelines - Add ES6 class development standards - Add documentation requirements - Remove outdated component templates and rules - Improve code organization and readability - Add TypeScript best practices - Add component structure guidelines - Add testing and accessibility requirements - Add style encapsulation recommendations This update provides clearer development guidelines for the project, particularly around Vue 3 component development and TypeScript usage. --- README-context.md | 308 +++++++++++++--------------------------------- 1 file changed, 84 insertions(+), 224 deletions(-) diff --git a/README-context.md b/README-context.md index 62130331..a22e2600 100644 --- a/README-context.md +++ b/README-context.md @@ -36,7 +36,6 @@ This application is built on a privacy-preserving claims architecture (via endor - **Merkle-Chained Claims**: Claims are cryptographically chained for verification and integrity - **Native and Web App**: Works on iOS, Android, and web browsers - ## User Journey The typical progression of usage follows these stages: @@ -47,7 +46,6 @@ The typical progression of usage follows these stages: 3. **Action Triggers**: Offers of help serve as triggers and motivations to execute proposed projects, moving from ideas to action. - ## Context for LLM Development When developing new functionality for Time Safari, consider these design principles: @@ -66,7 +64,6 @@ When developing new functionality for Time Safari, consider these design princip 7. **Low Resource Requirements**: The system should be lightweight enough to run on inexpensive devices users already own. - ## Use Cases to Support LLM development should focus on enhancing these key use cases: @@ -79,7 +76,6 @@ LLM development should focus on enhancing these key use cases: 4. **Governance Experimentation**: Features that facilitate decision-making and collective governance. - ## Constraints When developing new features, be mindful of these constraints: @@ -94,7 +90,38 @@ When developing new features, be mindful of these constraints: 5. **Offline-First When Possible**: Key functionality should work offline when feasible. -# Core Development Principles +## Project Technologies + +- Typescript using ES6 classes +- TailwindCSS +- Vite Build Tool +- Playwright E2E testing +- IndexDB +- Camera, Image uploads, QR Code reader, ... + +## Mobile Features + +- Deep Linking +- Local Notifications via a custom Capacitor plugin + +## Project Architecture + +- The application must work on web browser, PWA (Progressive Web Application), desktop via Electron, and mobile via Capacitor +- Building for each platform is managed via Vite + +## Core Development Principles + +- DRY development +- SOLID principles +- Law of Demeter +- Composition over Inheritence +- Interface Segregation +- Fail Fast +- Principle of Least Astonishment +- Information Hiding +- Single Source of Truth +- Principle of Least Privilege +- Continuous Integration/Continuous Deployment (CI/CD) - Ensure all components support accessibility first design - Implement privacy-preserving features by default - Support progressive enhancement across devices @@ -102,229 +129,62 @@ When developing new features, be mindful of these constraints: - Build trust-enabling interactions - Optimize for low resource requirements - Support offline-first functionality where possible +- Use class-based syntax with decorators from vue-facing-decorators. +- Should attempt to maximize Lighthouse Score as close to 100 as possible. +- Use Lighthouse for performance scoring + +## Vue Component Structure -# Vue Component Structure -- Use `@Options`, `@Ref`, `@Prop`, `@Emit`, and `@Watch` decorators for clear component structure +- Use `@Options`, `@Ref`, `@Prop`, `@Emit`, and `@Watch` Typescript decorators for clear component structure - Extend `Vue` class with proper type annotations for props, refs, and methods - Use Tailwind utility classes for accessible and responsive design - Avoid `setup()` or Composition API; use class syntax consistently - Keep methods pure when possible; extract logic into utilities - Ensure lifecycle methods are clearly defined inside class - Use semantic HTML + Tailwind classes for styling - -[rules.component-class] -description = "Create a privacy-aware Vue 3 component" -trigger = "vfd-component" -insert = """ -import { Options, Vue } from 'vue-facing-decorator' -import { PlatformService } from '@/services/platform' - -@Options({ - name: 'MyComponent', - props: {}, - emits: ['error', 'privacy-consent'], -}) -export default class MyComponent extends Vue { - private platformService = new PlatformService() - - // Lifecycle - mounted() { - this.checkPrivacyConsent() - } - - // Privacy check - private async checkPrivacyConsent() { - const hasConsent = await this.platformService.getPrivacyConsent() - if (!hasConsent) { - this.$emit('privacy-consent-needed') - } - } - - // Error handling - protected handleError(error: Error) { - console.error('Component error:', error) - this.$emit('error', error) - } -} -""" - -[rules.decorator-prop] -description = "Add a validated prop with privacy considerations" -trigger = "vfd-prop" -insert = """ -@Prop({ - required: true, - validator: (value: any) => { - // Add validation logic - return typeof value === 'string' && value.length > 0 - } -}) -propName!: string -""" - -[rules.decorator-watch] -description = "Watch a property with offline support" -trigger = "vfd-watch" -insert = """ -@Watch('myProp') -async onMyPropChanged(newVal: any, oldVal: any) { - try { - // Handle offline state - if (!navigator.onLine) { - await this.queueOfflineChange(newVal) - return - } - await this.processChange(newVal) - } catch (error) { - this.handleError(error as Error) - } -} -""" - -[rules.decorator-emit] -description = "Emit a privacy-aware event" -trigger = "vfd-emit" -insert = """ -@Emit('data-update') -async emitPrivateData() { - const privateData = await this.platformService.getEncryptedData() - return privateData -} -""" - -[rules.component-template] -description = "Create an accessible component template" -trigger = "vfd-component-full" -insert = """ - - - -""" - -[rules.async-method] -description = "Add an async method with offline support and error handling" -trigger = "vfd-async" -insert = """ -async fetchData(): Promise { - try { - if (!navigator.onLine) { - const cachedData = await this.getCachedData() - if (cachedData) { - this.data = cachedData - return - } - throw new Error('No cached data available offline') - } - - const response = await this.apiService.getData() - this.data = response - await this.cacheData(response) - } catch (error) { - this.handleError(error as Error) - this.$emit('error', error) - } -} -""" - -[rules.privacy-aware-component] -description = "Create a privacy-aware component with DID handling" -trigger = "vfd-privacy" -insert = """ -import { Options, Vue } from 'vue-facing-decorator' -import { PlatformService } from '@/services/platform' -import { DidService } from '@/services/did' - -@Options({ - name: 'PrivacyAwareComponent', - props: { - requiredPermissions: Array - } -}) -export default class PrivacyAwareComponent extends Vue { - private platformService = new PlatformService() - private didService = new DidService() - - requiredPermissions!: string[] - userDid = '' - - async mounted() { - await this.checkPermissions() - await this.initializeDid() - } - - private async initializeDid() { - try { - this.userDid = await this.didService.getCurrentDid() - } catch (error) { - this.handleError(error as Error) - } - } - - private async checkPermissions() { - for (const permission of this.requiredPermissions) { - const hasPermission = await this.platformService.checkPermission(permission) - if (!hasPermission) { - this.$emit('permission-required', permission) - return - } - } - } -} -""" \ No newline at end of file +- Pinia for state management + +## Vue Facing Decorators + +- Ensure all Vue 3 components are written using TypeScript with strict type checking enabled. +- Always include explicit types for props, emits, and reactive properties. +- When using @Options, ensure it includes metadata like name, template, or styles. +- Use @Prop for defining props with validation and default values. +- Use @Emit for emitting events with proper payload typing. +- Use @Watch for reactive property changes, and @Ref for DOM references." +- Organize Vue 3 components with a clear structure: imports at the top, followed by @Options metadata, then class properties (props, refs, reactive state), lifecycle hooks, methods, and finally @Watch or @Emit handlers. +- Ensure all props have explicit types and optional validation. +- Use TypeScript interfaces or types for complex prop structures. +- Validate default values for props where applicable. +- Use lifecycle hooks (e.g., onMounted, onUnmounted) sparingly and document their purpose. +- Avoid side effects in lifecycle hooks unless absolutely necessary. +- Use @Emit for emitting events with strongly typed payloads. +- Ensure event names are descriptive and match the action being performed. +- Use ref or reactive for managing internal state. +- Avoid overusing reactive state for simple values. Prefer computed properties for derived state. +- Write unit tests for components using Vue Test Utils and Jest/Vitest. +- Ensure tests cover props, events, and lifecycle behavior. +- Avoid unnecessary re-renders by using v-once for static content and memoizing expensive computations with computed properties. +- Ensure components are accessible by using semantic HTML and ARIA attributes. +- Use scoped styles or CSS modules to encapsulate styles. + +## es6 classes + +- Use ES6 class syntax with decorators (@Options, @Prop, @Emit). +- Use modular imports and default exports. +- Use arrow functions for methods and callbacks. +- Use destructuring for props and state. +- Provide default parameters for optional props or arguments. +- Use template literals for dynamic strings. +- Use spread/rest operators for object manipulation and arguments. +- Use const/let appropriately for variable declarations. +- Use enhanced object literals for cleaner syntax. +- Use async/await for asynchronous operations. +- Add scoped styles for encapsulation. +- Ensure accessibility with semantic HTML and ARIA attributes. + +## Documentation + +- Include JSDoc comments for all public methods and props. +- Files must have comments explaing contents and workflow of file +- Methods and props should explain role and workflow of each