Crucial Edge Cases & Anti-Patterns
This document outlines critical edge cases, known architectural limitations, and a consolidated list of anti-patterns. Adhering to these guidelines is crucial for maintaining application stability, security, and code quality.
Architectural Edge Cases & Limitations
Section titled “Architectural Edge Cases & Limitations”Backend: Manual and Inconsistent Workspace Scoping
Section titled “Backend: Manual and Inconsistent Workspace Scoping”A critical aspect of the backend architecture is its multi-tenant data isolation, which is handled by workspace_id scoping. However, this is not a “set-it-and-forget-it” system.
- Scoping is Manual: GORM does not have a default, automatic scope to enforce workspace isolation. Developers must manually add
.Where("workspace_id = ?", ...)to every single database query, for both list and detail/update/delete operations. - Inconsistency Risk: Because it’s a manual process, it is easy to forget. Some older modules or less-used repositories may have missing workspace checks.
- Known Flaw: An audit of
internal/repository/outlet_repository.gorevealed that theGetByID,Update, andDeletemethods are missing workspace scoping. This is a potential security vulnerability, as a user from one workspace could theoretically access or modify data in another if they can guess the record ID.
Mobile: “Offline-First” for Reads Only (No Mutation Queue)
Section titled “Mobile: “Offline-First” for Reads Only (No Mutation Queue)”The mobile application is described as “offline-first,” but this primarily applies to data reading, not writing.
- Cached Reads: TanStack Query is configured with
networkMode: 'offlineFirst'. This means any data fetched while online is cached via MMKV. If the app goes offline, it will serve this cached data, allowing for read-only access to previously viewed information. - No Offline Mutations: The application does not have an offline mutation queue. Any attempt to create, update, or delete data (e.g., submitting a form, updating a profile) will fail if the device is offline.
- Implication: There is no automatic synchronization or replaying of failed mutations when the network becomes available again. Users must be online to make any changes. This is a significant limitation of the current “offline-first” strategy.
Consolidated Anti-Patterns
Section titled “Consolidated Anti-Patterns”This list combines the “DO NOT” sections from all three repository rulebooks.
Backend (Go) Anti-Patterns
Section titled “Backend (Go) Anti-Patterns”- DO NOT put SQL/GORM calls directly in handlers. Use the repository layer.
- DO NOT use
c.JSONfor responses. Always useutils.HandleResponsefor standardized API output. - DO NOT skip
workspace_idscoping on any query. This is a security and data-integrity requirement. - DO NOT skip
middleware.RequirePermissionon any new route. All endpoints must have RBAC enforcement. - DO NOT use raw SQL unless it is a pre-existing pattern in the module you are editing.
- DO NOT create “god handlers” or “god services” with hundreds of lines of mixed concerns. Keep them focused.
- DO NOT use
interface{}in DTOs or models. Use strongly-typed structs.
Web (React) Anti-Patterns
Section titled “Web (React) Anti-Patterns”- DO NOT use
useEffect+useStatefor fetching server data. Always use TanStack Query hooks. - DO NOT load full datasets for tables. All lists with more than a handful of items must use server-side pagination.
- DO NOT create custom modal or table components if
DialogTableorCommonTablecan be used. - DO NOT hardcode API URLs. Use the shared
lib/api.tsAxios instance. - DO NOT mix filter state (URL search params) with local component UI state.
- DO NOT create new UI components if a suitable one exists in
shadcn/ui. - DO NOT allow filter parameter names (
project_id) to mismatch the backendform:"..."tags.
Mobile (React Native) Anti-Patterns
Section titled “Mobile (React Native) Anti-Patterns”- DO NOT use
AsyncStorageorSQLite. The only permitted storage is MMKV. - DO NOT use
Redux,MobX, or ReactContextfor global state. Use Jotai. - DO NOT introduce new UI libraries (e.g.,
react-native-elements). The only permitted UI library is React Native Paper MD3. - DO NOT use
NativeWindorTailwind. Styling must be done withStyleSheet.create. - DO NOT use inline styles (e.g.,
style={{ flex: 1 }}). This creates new objects on every render and hurts performance. - DO NOT use
defaultexports anywhere. All components, hooks, and services must usenamedexports and be barrel-exported from anindex.tsfile. - DO NOT store server data in local state (
useState, Jotai atoms). All server state must be managed by TanStack Query. - DO NOT create a new query without setting
networkMode: 'offlineFirst'. - DO NOT forget to memoize list item components with
React.memo. - DO NOT pass large, complex objects as navigation parameters. Pass IDs and fetch the data in the target screen.