-
Notifications
You must be signed in to change notification settings - Fork 8
Development Guide
The goal of this guide is to keep our workflow efficient, our codebase clean, and our communication clear. Though not everything may be straightforward at first.
- β Follow the guide as closely as possible. Itβs designed to prevent confusion and improve collaboration.
- β If something is unclear or youβre unsure how to proceed please let me (
@mahid797
) know. - π Got suggestions? If you think part of this guide can be improved, bring it upβIβm open to feedback!
Coding consistency and clarity are critical for collaboration, maintainability, and scalability.This section covers the essential practices every developer should follow when writing code for Datahall.
-
Use Prettier for Formatting
- A
.prettierrc
file is provided in the repository. - All code must be formatted with Prettier before committing.
- This ensures consistency in tabs, semicolons, quotes, and other stylistic choices.
- A
-
Meaningful Naming
- Choose clear, descriptive names for variables, functions, and components.
- Avoid abbreviations or overly short identifiers (e.g.,
fn
ortmp
) unless they are standard (e.g.,id
).
-
Small, Focused Files
- Aim to keep files under ~200 lines. If a file grows beyond that, consider splitting it into smaller, logical parts.
- This keeps the code easier to navigate, read, and maintain.
-
Avoid Reinventing the Wheel
- Before writing a new hook, component, or utility, check existing ones in the codebase.
- Small modifications to existing code are preferable to duplicating logic.
- As the saying goes, βDonβt reinvent the wheel.β
-
Commenting and Documentation
- Add concise inline comments for complex logic.
- For public-facing or reusable functions, include brief JSDoc/TSDoc annotations to clarify parameter types and return values.
-
TypeScript Usage
- Use TypeScript interfaces and types for function parameters, return values, component props, and hooks.
- Keep shared models/types in the
shared/models/
orshared/types/
folders. - While we donβt enforce specific TS compiler flags beyond the defaults, strict typing is encouraged to catch errors early.
π‘ Pro Tip: Take short breaks when your brain feels fried. A quick stretch or β can save you from tunnel vision!
-
All API Calls in Hooks
-
No direct API calls in componentsβcreate or use existing hooks in
src/hooks/
. - Organize hooks by domain (e.g.,
hooks/documents/
,hooks/auth/
) rather than lumping everything together.
-
No direct API calls in componentsβcreate or use existing hooks in
-
Preferred Libraries
- TanStack Query (or React Query) for data fetching, caching, and mutations.
- This ensures consistent handling of loading states, error states, and caching strategies.
-
TanStack Query Usage Tips
-
Domain-Specific Keys: When creating queries, use descriptive keys (e.g.,
['documents', docId]
) so that your caching and invalidation remain accurate. -
Invalidate on Mutations: Always invalidate relevant queries
(
queryClient.invalidateQueries(['documents'])
) after successful mutations to keep data fresh. -
No Direct
axios
orfetch
in Components: All network calls should live in hooks; components should just consume hook data.
-
Domain-Specific Keys: When creating queries, use descriptive keys (e.g.,
-
Component Guidelines
-
Reusable UI Components go under
src/components/
, grouped by category (common/
,input/
,loaders/
, etc.). -
Feature-Specific Components can live inside their respective feature folders (e.g.,
app/documents/[documentId]/components/
).
-
Reusable UI Components go under
-
Styling
- Use Material UI (MUI) components and sx props for one-off styling or small modifications.
- Larger or repeated style patterns can go into global or theme-based styles (
theme/
folder). - Avoid adding multiple styling libraries to keep the bundle lean and the styles consistent.
-
Error Handling
- In most cases, rely on try/catch in hooks or fetch logic to handle errors gracefully.
- Display user-friendly error messages (e.g., using a toast) whenever an API request fails.
- If needed, Reactβs error boundaries can be used for critical failures.
π‘ Pro Tip: If you spot a component that might be useful in other parts of the app, refactor it to be reusable and share the love! β€οΈ
-
Services for Business Logic
- All database operations and critical logic must be placed in
src/app/api/_services/
. -
API route handlers (
route.ts
) should remain thin and delegate work to their corresponding service functions.
- All database operations and critical logic must be placed in
-
No Direct Prisma in Routes
- Import the relevant service in
route.ts
and call it. - This pattern keeps your routes readable and encourages reusability/testing of the service layer.
- Import the relevant service in
-
Error Handling
- Use try/catch blocks in service functions if your logic can throw.
- Return standardized error responses to the client so they can handle them consistently.
-
File & Folder Size
- As with frontend, keep files under ~200 lines where possible.
- Break large services into smaller domain-specific files if they become too large or cluttered.
π‘ Pro Tip: A well-organized backend means fewer late-night debugging sessions. Sleep is precious! π΄
-
Environment Files
-
Never commit
.env
or.env.local
files to the repository. - Keep secrets (API keys, database credentials) in environment variables.
- If new environment variables are introduced, document them in the projectβs README or
.env.example
.
-
Never commit
-
Reusability & Modularity
- Look for existing utilities, hooks, or components before creating new ones.
- Maintain a logical hierarchy: if code is used in multiple places, move it to a more generic
folder (
utils/
,components/
, or a relevant domain folder).
-
Consistency Over Individual Preference
- Adhere to established patterns (naming, file structure, code style) even if you prefer a different style.
- Consistency greatly reduces confusion in a growing team and codebase.
π‘ Pro Tip: Great code is a team effort! Donβt hesitate to ask for help or review.
A well-defined structure makes it easier for everyone to navigate, contribute, and scale the codebase. Below are guidelines on how to organize your files and folders for both frontend and backend in Bluewave Datahall. Consistency is keyβif in doubt, ask the team or check existing patterns before creating a new folder or file structure.
A typical Next.js App Router layout means feature-related routes and pages go under src/app/
.
We group things by feature (e.g., documents
, links
, profile
) to keep them logical and
discoverable.
-
Next.js App Router
- Organize pages/routes under
src/app/<feature>/
. Each feature folder might have subfolders like[documentId]
,[linkId]
, etc. - Keep route definitions (
page.tsx
,layout.tsx
) straightforward; heavy business logic or specialized UI goes in subfolders or separate components.
- Organize pages/routes under
-
Components
-
Reusable UI components go under
src/components/
, grouped by domain (e.g.,common/
,input/
,loaders/
,fileHandling/
, etc.). - If a component is only relevant to one feature, you may keep it in that featureβs folder (e.g.,
app/documents/[documentId]/components/
). - Strive to keep them small, focused, and easy to reuse.
-
Reusable UI components go under
-
Hooks
- Place all custom hooks in
src/hooks/
(or subfolders likesrc/hooks/documents/
,src/hooks/auth/
, etc.) to keep them discoverable. -
Create one file per hook: Each hook (e.g.,
useDocuments.ts
,useAddDocument.ts
) should live in its own file rather than bundling multiple hooks together. -
Domain-Based Organization: For example, if you have multiple document-related hooks
(
useDocuments.ts
,useDeleteDocument.ts
,useAddDocument.ts
), store them undersrc/hooks/documents/
. -
TanStack Query Integration: Hooks should encapsulate all query, mutation, and caching
logic, ensuring components donβt call
axios
orfetch
directly.
- Place all custom hooks in
-
Shared & Theming
- Common helpers, data models, and utilities now reside in
src/shared/
. For instance:src/shared/models/
src/shared/types/
src/shared/utils/
- MUI theming files are in
src/theme/
(e.g.,globalTheme.ts
,mainTheme.ts
). - Keep frequently reused style objects or CSS snippets accessible in a shared location to maintain consistency.
- Common helpers, data models, and utilities now reside in
-
Example Frontend Structure
src/ βββ app/ β βββ documents/ β β βββ [documentId]/ β β β βββ components/ β β β β βββ DocumentView.tsx β β β β βββ FilterToggle.tsx β β β β βββ InfoTable.tsx β β β βββ loading.tsx β β β βββ page.tsx β β βββ components/ β β β βββ DocumentsTable.tsx β β β βββ DragAndDropBox.tsx β β β βββ ... β β βββ page.tsx β βββ links/ β β βββ [linkId]/ β β β βββ components/ β β β β βββ FileAccessContainer.tsx β β β β βββ FileDisplay.tsx β β β βββ layout.tsx β β β βββ loading.tsx β β β βββ page.tsx β βββ profile/ β β βββ components/ β β βββ page.tsx β βββ providers.tsx β βββ layout.tsx β βββ page.tsx βββ components/ β βββ layout/ β βββ navigation/ β βββ input/ β βββ loaders/ β βββ fileHandling/ β βββ common/ β βββ modals/ β βββ index.ts βββ hooks/ β βββ documents/ β β βββ useDocuments.ts β β βββ ... β βββ auth/ β βββ useModal.ts β βββ useToast.ts β βββ ... βββ icons/ π All application icons βββ shared/ β βββ models/ π Data models for different domains β βββ types/ π Global TypeScript types β βββ utils/ π Shared utility functions βββ theme/ βββ mainTheme.ts π¨ MUI global theme configuration
π‘ Pro Tip: Always keep file size in check (aim for ~200 lines or less). If a hook becomes too large or handles multiple responsibilities, consider splitting it into smaller, logical parts.
Our backend uses Next.js API routes under src/app/api/
. We rely on services in
src/app/api/_services/
to handle database logic, ensuring route handlers remain light and easy to
maintain.
-
API Routes & Services
-
src/app/api/
contains Next.js API routes, grouped by feature (auth/
,documents/
,public_links/
, etc.). - Each feature folder can have its own subfolders (e.g.,
[documentId]/
,[linkId]/
). -
All database logic goes into
src/app/api/_services/
(e.g.,authService.ts
,documentService.ts
,linkService.ts
).
-
-
No Prisma in Routes
- Keep route handlers lean: parse requests, call the relevant service, and return a response.
- The actual Prisma interactions live in service files.
-
Structure Example
src/ βββ app/ βββ api/ β βββ auth/ β β βββ [...nextauth]/ β β βββ verify/ β β βββ register/ β β βββ password/ β β βββ forgot/route.ts β β βββ reset/route.ts β βββ documents/ β β βββ route.ts β β βββ [documentId]/ β β β βββ route.ts β β β βββ links/ β β β β βββ route.ts β β β β βββ [linkId]/route.ts β β β βββ visitors/route.ts β βββ public_links/ β β βββ [linkId]/route.ts β β βββ [linkId]/access/route.ts β βββ profile/ β β βββ changeName/ β β β βββ route.ts β β βββ changePassword/ β β β βββ route.ts β β βββ route.ts β βββ _services/ β β βββ authService.ts β β βββ emailService.ts β β βββ documentService.ts β β βββ linkService.ts β β βββ ...
-
Keeping Services Manageable
- If a service handles too many responsibilities, split it into multiple files (e.g.,
documentService.ts
,documentAnalyticsService.ts
). - Use clear function names like
getUserById
,updateDocument
, etc.
- If a service handles too many responsibilities, split it into multiple files (e.g.,
-
Shared Utilities
- A single file (like
src/lib/prisma.ts
) often initializes the Prisma client to keep everything consistent. - Additional backend helpers (e.g., error formatting, input validation) can live in
_services/util/
orsrc/shared/utils/
if theyβre used project-wide.
- A single file (like
π‘ Pro Tip: Keep your async/await usage consistent; mixing it with
.then()
can lead to confusion. A well-organized backend means fewer frantic searches at 2 AM.
Frontend | Backend |
---|---|
- Feature folders under src/app/ (Next.js App Router).- Reusable components in src/components/ .- Domain-based hooks in src/hooks/ .- Shared models, types, and utilities in src/shared/ .- Theming in src/theme/ . |
- Feature-based route folders under src/app/api/ .- All Prisma logic in src/app/api/_services/ .- Route files stay thin, delegating to services. - Shared config/utilities in src/lib/ or src/shared/utils/ . |
By following this structure, you ensure that the codebase remains maintainable, discoverable, and easy to expand as new features are added.
- Keep file sizes small (~200 lines max).
- Donβt duplicate logicβif somethingβs used in multiple places, centralize it.
A well-structured GitHub workflow helps the team stay organized, prioritize tasks, and ensure that every change is tracked and reviewed properly. Below are our conventions for issues, branching, and pull requests in Bluewave Datahall.
-
Creating Issues
- Provide a clear title and detailed description.
- Include acceptance criteria, subtasks, or screenshots (if relevant) to help clarify the requirements.
- Assign a priority level (see 3.2 Issue Priority Levels below) and add labels (e.g.,
Frontend
,Backend
,Refactor
) as needed to categorize your issue.
-
Issue Statuses
- To Do: Newly created issues that havenβt been started.
- In Progress: Actively being worked on.
- In Review: A pull request (PR) has been created and is awaiting review.
- Done: Once the code has been reviewed and deployed successfully, I will close the issue (developers should not close issues themselves).
-
Ownership & Assignments
- When you begin work on an issue, assign yourself (if unassigned) and move it to In Progress.
- If you need help or are blocked, communicate in the issue or tag another developer π¬.
-
Donβt Forget β¨
- Never close issues yourself β let the project lead handle it after verifying the merge.
- Update the issue status promptly to reflect your progress.
Every issue in this project will have one of the following five priorities. Developers should use these levels to decide what to work on next and how quickly an issue should be addressed.
-
π₯Critical
- Definition: Completely obstructs core functionality or causes major service interruptions.
- Action: Must be resolved before all other tasks. If an issue is deemed βHigh Priorityβ (i.e., critical for an upcoming deadline), it falls under this category. Stop lower-priority work to address it immediately.
-
β‘Important
- Definition: A significant problem or feature that needs resolution before the upcoming release or milestone.
- Action: Work on these right after addressing any Critical issues. They often involve bugs that risk deadlines or features essential to user satisfaction.
-
π±Nice-to-Have
- Definition: Useful improvements, UI refinements, or optimizations that add value without being urgent.
- Action: Tackle these once more pressing issues (Critical or Important) are under control. They often enhance usability or maintainability.
-
π οΈBacklog
- Definition: Tasks or ideas not needed for the current release cycle or immediate roadmap.
- Action: Schedule these for later or pick them up during quieter periods; they have minimal immediate impact on users.
-
π₯Icebox
- Definition: Low-priority or speculative ideas that may or may not be addressed in the future.
- Action: No current plans to tackle; revisit periodically to see if new information or resources make them more relevant.
Handling Priorities
- Critical issues always come firstβaddress them before everything else.
- If you finish your assigned tasks or are unsure what to tackle next, check for Critical or Important items.
- For issues that initially lack clarity or need discussion, add a Needs Review or Question label to them and collaborate with the team to refine their scope.
A clear branching strategy prevents conflicts and keeps our release process smooth.
-
Base Branch
- Always branch off of
dev
. -
Never branch from
master
unless explicitly told.
- Always branch off of
-
Branch Naming Conventions
-
feature/ for new features (e.g.,
feature/document-analytics
). -
fix/ for bug fixes (e.g.,
fix/login-error
). - hotfix/ for critical fixes that need immediate attention.
-
refactor/ for refactoring efforts (e.g.,
refactor/hooks-structure
).
-
feature/ for new features (e.g.,
-
No Direct Commits
-
Do not commit or push directly to
dev
ormaster
. - Always work on a feature/fix branch and submit a pull request (PR).
-
Do not commit or push directly to
-
Keep Your Branch Updated
- Before opening (or merging) a PR, rebase or pull the latest changes from
dev
to avoid merge conflicts and ensure your branch is in sync.
- Before opening (or merging) a PR, rebase or pull the latest changes from
π‘ Pro Tip: Keep your branches small and focused. A tidy branch is easier to review and merge!
All changes, no matter how small, should be submitted via PR.
-
When to Create a PR
- As soon as you have a working slice of functionality (or bug fix), open a PR.
- This allows for early feedback and avoids massive, hard-to-review PRs.
-
PR Requirements
-
Base branch: Always set
dev
as the target. -
Link issues: Reference related issues using keywords like
Closes #123
. - Description: Provide a concise summary of what changed and why.
- Screenshots: If there are UI changes, include before/after visuals πΈ.
-
Base branch: Always set
-
Review Process
- Add me (
@mahid797
) as a reviewer. - Do not merge your own PRβwait for review and approval.
- Address review comments promptly; if you disagree, provide clear reasoning.
- Add me (
-
Never Close Issues or Merge Your Own PR
- After approval, the project lead will handle merging.
- Once the merge is verified, the project lead will close the issue.
-
Checklist β
- Code follows coding and structuring guidelines.
- Code is formatted using Prettier.
- No unused variables, imports, or commented code.
- Issue(s) linked.
-
dev
is the merge target.
Though not strictly enforced, using a consistent pattern makes it easier to scan commit history.
-
Format:
<type>(scope): short description
-
Types:
feat
,fix
,refactor
,docs
,style
, etc. -
Scope: The part of the project affected (e.g.,
auth
,documents
).
-
Types:
-
Examples
feat(documents): add new endpoint for analytics
fix(auth): correct login session bug
refactor(hooks): restructure document hooks for clarity
Following this workflow ensures a clear, auditable history of changes and keeps everyone aligned:
- Create & assign issues with clear descriptions and priorities.
-
Branch off
dev
with meaningful names. - Open a PR for all changes, link issues, and add me as a reviewer.
- Donβt merge your own PR or close issuesβwait for final review.