From c018c5ececa8c074907040ecf3e5d40f498277db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 Aug 2025 02:24:25 +0000 Subject: [PATCH 1/5] Initial plan From 688dc99b0e7fdd91bc395c04f803b8ff1e57f1e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 Aug 2025 02:30:21 +0000 Subject: [PATCH 2/5] Add comprehensive organization-wide Copilot instructions Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> --- .github/copilot-instructions.md | 220 ++++++++++++++++++++++++++++++++ README.md | 17 +++ 2 files changed, 237 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..35836f7 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,220 @@ +# SwitchbackTech Organization - GitHub Copilot Instructions + +## Organization Overview + +**Mission**: Building intentional software that helps people value their time. + +**Primary Product**: Compass Calendar - a minimalist weekly planner that integrates seamlessly with Google Calendar, designed for people who want to reclaim control over their schedule without overwhelming complexity. + +**Philosophy**: +- Intentional software design - every feature serves a clear purpose +- Minimalist user experience - powerful functionality without clutter +- Time-conscious development - respect both user time and developer time +- Open source and community-driven + +## Tech Stack & Architecture + +### Core Technologies +- **Frontend**: React 18+, TypeScript, Styled Components +- **Backend**: Node.js, Express.js, TypeScript +- **Database**: MongoDB with Mongoose ODM +- **Real-time**: Socket.io for live updates +- **Authentication**: Supertokens for session management +- **Testing**: Jest, React Testing Library +- **Build**: Webpack, Yarn workspaces (monorepo) +- **Cloud**: Google Cloud Platform +- **Integration**: Google Calendar API, Google OAuth + +### Architecture Patterns +- **Monorepo Structure**: Use Yarn workspaces with packages/* organization +- **Clean Architecture**: Separate concerns between core business logic, API, and UI +- **Component-Driven**: React components should be reusable and composable +- **Type Safety**: Strict TypeScript configuration with proper type definitions +- **Functional Programming**: Prefer pure functions and immutable data patterns + +## Coding Standards & Conventions + +### General Principles +1. **Clarity over cleverness** - code should be immediately understandable +2. **Consistency** - follow established patterns within each package +3. **Performance-conscious** - especially for calendar rendering and real-time updates +4. **Accessibility** - semantic HTML and ARIA labels for screen readers +5. **Mobile-first** - responsive design starting from mobile viewport + +### TypeScript Guidelines +- Use strict mode with `noImplicitAny` and `strictNullChecks` +- Prefer interfaces over types for object shapes +- Use proper generic types for reusable components +- Export types alongside implementation code +- Use meaningful type names that describe the domain (e.g., `CalendarEvent`, `TimeSlot`) + +### React Best Practices +- Use functional components with hooks +- Keep components small and focused on single responsibility +- Use custom hooks for shared logic +- Prefer composition over inheritance +- Use React.memo() for performance optimization when needed +- Follow the "lift state up" principle for shared state + +### File & Folder Conventions +- Use kebab-case for file names +- Co-locate tests next to source files (not separate test directories) +- Use index.ts files for clean imports +- Group related functionality in feature folders +- Follow the existing package structure: `packages/{backend,core,web,scripts}` + +### Naming Conventions +- **Components**: PascalCase (e.g., `CalendarView`, `EventCard`) +- **Functions**: camelCase with descriptive verbs (e.g., `createEvent`, `formatTimeSlot`) +- **Constants**: SCREAMING_SNAKE_CASE (e.g., `DEFAULT_TIME_ZONE`) +- **Types/Interfaces**: PascalCase with descriptive names (e.g., `GoogleCalendarEvent`) + +## Domain-Specific Guidance + +### Calendar & Time Management +- Always consider time zones when working with dates +- Use moment.js or date-fns for consistent date manipulation +- Implement proper handling for recurring events +- Consider performance for large date ranges +- Maintain consistency with Google Calendar conventions + +### User Experience Priorities +1. **Speed**: Calendar operations should feel instantaneous +2. **Simplicity**: Default to the simplest solution that works +3. **Shortcuts**: Power users should have keyboard shortcuts +4. **Offline resilience**: Graceful degradation when offline +5. **Minimal clicks**: Reduce the number of interactions needed + +## Repository-Specific Guidelines + +### `compass` (Main Application) +- Follow the existing monorepo structure with backend, core, and web packages +- Use the established testing patterns with Jest +- Maintain the existing component library patterns +- Consider Google Calendar sync implications for any data changes +- Test thoroughly with the staging environment before production + +### `compass-docs` (Documentation) +- Use Docusaurus conventions and components +- Keep documentation up-to-date with code changes +- Include code examples for complex features +- Maintain consistency with the main app's terminology + +### `.github` (Organization Config) +- Follow GitHub best practices for workflows and templates +- Keep organization-wide configurations minimal and focused +- Test any workflow changes in a fork first + +## Testing Requirements + +### Coverage Expectations +- **Unit Tests**: All business logic functions must have tests +- **Integration Tests**: API endpoints and database operations +- **Component Tests**: React components with user interaction scenarios +- **E2E Tests**: Critical user flows like event creation and sync + +### Testing Patterns +- Use descriptive test names that explain the scenario +- Follow Arrange-Act-Assert pattern +- Mock external dependencies (Google API, database) +- Test error conditions and edge cases +- Use factories or fixtures for test data + +## Performance Considerations + +### Frontend Performance +- Optimize calendar rendering for large date ranges +- Use React.memo() and useMemo() for expensive calculations +- Implement virtual scrolling for long lists +- Minimize re-renders during drag-and-drop operations +- Lazy load non-critical components + +### Backend Performance +- Use database indexes for calendar queries +- Implement proper caching for Google Calendar sync +- Use connection pooling for database operations +- Monitor and optimize API response times +- Consider rate limiting for external API calls + +## Security Guidelines + +### Data Protection +- Never log sensitive user data (calendar events, personal info) +- Use proper validation for all user inputs +- Implement CSRF protection for state-changing operations +- Follow OAuth best practices for Google integration +- Use environment variables for all sensitive configuration + +### Authentication & Authorization +- Use Supertokens for consistent session management +- Implement proper role-based access if needed +- Validate user permissions for calendar operations +- Use secure session cookies +- Implement proper logout functionality + +## Documentation & Learning Resources + +### Internal Documentation +- **Main docs**: https://docs.compasscalendar.com +- **Contributing guide**: Follow conventions at docs.compasscalendar.com/docs/contribute/convention-guide +- **Setup guide**: Available in main repository README +- **API documentation**: Generated from TypeScript types + +### External References +- **Google Calendar API**: https://developers.google.com/calendar +- **React best practices**: https://react.dev/learn +- **TypeScript handbook**: https://www.typescriptlang.org/docs/ +- **Accessibility guidelines**: https://www.w3.org/WAI/WCAG21/quickref/ + +## Common Patterns & Examples + +### Event Creation Pattern +```typescript +interface CalendarEvent { + id: string; + title: string; + start: Date; + end: Date; + description?: string; + location?: string; + isRecurring: boolean; + googleEventId?: string; +} + +const createEvent = async (event: Omit): Promise => { + // Validate time boundaries + // Sync with Google Calendar + // Store in local database + // Return created event +}; +``` + +### Component Structure Pattern +```typescript +interface EventCardProps { + event: CalendarEvent; + onEdit: (event: CalendarEvent) => void; + onDelete: (eventId: string) => void; + isEditable?: boolean; +} + +export const EventCard: React.FC = ({ event, onEdit, onDelete, isEditable = true }) => { + // Component implementation +}; +``` + +## Error Handling + +### Frontend Error Boundaries +- Use React Error Boundaries for component-level errors +- Provide meaningful error messages to users +- Log errors for debugging but never expose sensitive data +- Implement graceful fallbacks for failed operations + +### Backend Error Handling +- Use consistent error response format +- Log errors with appropriate context +- Handle Google API rate limits gracefully +- Provide retry mechanisms for transient failures + +Remember: The goal is to build software that genuinely improves how people manage their time, without adding unnecessary complexity to their lives or to the codebase. \ No newline at end of file diff --git a/README.md b/README.md index 888fadf..1755fe8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # .github Intentional software + +## Organization-Wide Configuration + +This repository contains organization-wide GitHub configuration for SwitchbackTech. + +### GitHub Copilot Instructions + +The `.github/copilot-instructions.md` file provides comprehensive coding guidelines and context for GitHub Copilot across all SwitchbackTech repositories. It includes: + +- Organization mission and philosophy +- Tech stack preferences and architectural patterns +- Coding standards and conventions +- Domain-specific guidance for calendar/time management software +- Testing and performance requirements +- Security guidelines and best practices + +These instructions help ensure consistent, high-quality code generation that aligns with SwitchbackTech's "intentional software" philosophy. From 0911fecb94f259f3e7483d10ed8844d9882ba217 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 Aug 2025 02:39:42 +0000 Subject: [PATCH 3/5] Replace moment.js/date-fns with dayjs in Copilot instructions Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 35836f7..202a303 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -73,7 +73,7 @@ ### Calendar & Time Management - Always consider time zones when working with dates -- Use moment.js or date-fns for consistent date manipulation +- Use dayjs for consistent date manipulation - Implement proper handling for recurring events - Consider performance for large date ranges - Maintain consistency with Google Calendar conventions From e3edf70315c220e33e15deb8166c468f550a1992 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 Aug 2025 02:46:50 +0000 Subject: [PATCH 4/5] Remove extra README.md changes - keep only copilot-instructions.md Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> --- README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/README.md b/README.md index 1755fe8..888fadf 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,2 @@ # .github Intentional software - -## Organization-Wide Configuration - -This repository contains organization-wide GitHub configuration for SwitchbackTech. - -### GitHub Copilot Instructions - -The `.github/copilot-instructions.md` file provides comprehensive coding guidelines and context for GitHub Copilot across all SwitchbackTech repositories. It includes: - -- Organization mission and philosophy -- Tech stack preferences and architectural patterns -- Coding standards and conventions -- Domain-specific guidance for calendar/time management software -- Testing and performance requirements -- Security guidelines and best practices - -These instructions help ensure consistent, high-quality code generation that aligns with SwitchbackTech's "intentional software" philosophy. From 66e866f4a3835e8624236a31a971c7f4e0e1a908 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 Aug 2025 03:29:07 +0000 Subject: [PATCH 5/5] Update TypeScript interfaces to match actual Compass repository patterns Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> --- .github/copilot-instructions.md | 139 +++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 27 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 202a303..8cb1721 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -46,7 +46,9 @@ - Prefer interfaces over types for object shapes - Use proper generic types for reusable components - Export types alongside implementation code -- Use meaningful type names that describe the domain (e.g., `CalendarEvent`, `TimeSlot`) +- Use meaningful type names that describe the domain (e.g., `Schema_Event`, `Schema_GridEvent`) +- Use Zod schemas for runtime validation (e.g., `CoreEventSchema`, `GridEventSchema`) +- Extend base schemas when adding functionality (e.g., `GridEventSchema.extend()`) ### React Best Practices - Use functional components with hooks @@ -64,19 +66,25 @@ - Follow the existing package structure: `packages/{backend,core,web,scripts}` ### Naming Conventions -- **Components**: PascalCase (e.g., `CalendarView`, `EventCard`) +- **Components**: PascalCase (e.g., `GridEvent`, `SomedayEventContainer`) - **Functions**: camelCase with descriptive verbs (e.g., `createEvent`, `formatTimeSlot`) -- **Constants**: SCREAMING_SNAKE_CASE (e.g., `DEFAULT_TIME_ZONE`) -- **Types/Interfaces**: PascalCase with descriptive names (e.g., `GoogleCalendarEvent`) +- **Constants**: SCREAMING_SNAKE_CASE (e.g., `DEFAULT_TIME_ZONE`, `SOMEDAY_WEEKLY_LIMIT`) +- **Types/Interfaces**: PascalCase with descriptive names (e.g., `Schema_Event`, `Schema_GridEvent`) +- **Enum Values**: SCREAMING_SNAKE_CASE (e.g., `Priorities.UNASSIGNED`, `Origin.GOOGLE`) +- **Props Interfaces**: ComponentName + "Props" (e.g., `GridEventProps`, `EventFormProps`) ## Domain-Specific Guidance +### Domain-Specific Guidance + ### Calendar & Time Management - Always consider time zones when working with dates - Use dayjs for consistent date manipulation -- Implement proper handling for recurring events +- Implement proper handling for recurring events using `recurrence.rule` and `recurrence.eventId` - Consider performance for large date ranges - Maintain consistency with Google Calendar conventions +- Use proper field names: `startDate`/`endDate` (not `start`/`end`) +- Handle Google Calendar integration via `gEventId` and `gRecurringEventId` fields ### User Experience Priorities 1. **Speed**: Calendar operations should feel instantaneous @@ -168,39 +176,116 @@ ## Common Patterns & Examples -### Event Creation Pattern +### Event Types and Interfaces ```typescript -interface CalendarEvent { - id: string; - title: string; - start: Date; - end: Date; - description?: string; - location?: string; - isRecurring: boolean; - googleEventId?: string; +// Core event interface from @core/types/event.types +interface Schema_Event { + _id?: string; + allDayOrder?: number; + description?: string | null | undefined; + endDate?: string; + isAllDay?: boolean; + isSomeday?: boolean; + gEventId?: string; + gRecurringEventId?: string; + order?: number; + origin?: Origin; + priority?: Priority; + recurrence?: { + rule?: string[]; + eventId?: string; + }; + startDate?: string; + title?: string; + updatedAt?: Date | string; + user?: string; +} + +// Grid event interface from @web/common/types/web.event.types +interface Schema_GridEvent extends Schema_Event { + hasFlipped?: boolean; + isOpen?: boolean; + row?: number; + position: { + isOverlapping: boolean; + widthMultiplier: number; + horizontalOrder: number; + dragOffset: { y: number }; + initialX: number | null; + initialY: number | null; + }; +} + +// Priority enum from @core/constants/core.constants +enum Priorities { + UNASSIGNED = "unassigned", + WORK = "work", + SELF = "self", + RELATIONS = "relationships", } -const createEvent = async (event: Omit): Promise => { - // Validate time boundaries - // Sync with Google Calendar +type Priority = Priorities.UNASSIGNED | Priorities.WORK | Priorities.SELF | Priorities.RELATIONS; +``` + +### Event Creation Pattern +```typescript +const createEvent = async (event: Omit): Promise => { + // Validate time boundaries with dayjs + const start = dayjs(event.startDate); + const end = dayjs(event.endDate); + + // Sync with Google Calendar if needed // Store in local database - // Return created event + // Return created event with _id }; ``` ### Component Structure Pattern ```typescript -interface EventCardProps { - event: CalendarEvent; - onEdit: (event: CalendarEvent) => void; - onDelete: (eventId: string) => void; - isEditable?: boolean; +interface GridEventProps { + event: Schema_GridEvent; + isDraft: boolean; + isDragging: boolean; + isPlaceholder: boolean; + isResizing: boolean; + isRecurring: boolean; + isInPast: boolean; + measurements: Measurements_Grid; + onEventMouseDown: (event: Schema_GridEvent, e: MouseEvent) => void; + onScalerMouseDown: ( + event: Schema_GridEvent, + e: MouseEvent, + dateToChange: "startDate" | "endDate", + ) => void; + weekProps: WeekProps; } -export const EventCard: React.FC = ({ event, onEdit, onDelete, isEditable = true }) => { - // Component implementation -}; +export const GridEvent = memo(forwardRef( + ({ event, isDraft, isDragging, ...props }, ref) => { + const isRecurring = event.recurrence && event.recurrence?.eventId !== null; + const isInPast = dayjs().isAfter(dayjs(event.endDate)); + + return ( + + {/* Component implementation */} + + ); + } +)); +``` + +### Import Patterns +```typescript +import dayjs from "dayjs"; +import { Priorities, Origin } from "@core/constants/core.constants"; +import { Schema_Event, Schema_GridEvent } from "@core/types/event.types"; +import { Schema_GridEvent as WebGridEvent } from "@web/common/types/web.event.types"; ``` ## Error Handling