diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..bfcb663 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,63 @@ +name: Bug Report +description: Report a bug or unexpected behavior +title: "[Bug]: " +labels: ["bug"] +body: + - type: textarea + id: description + attributes: + label: Description + description: A clear description of the bug. + placeholder: What happened? + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: How can we reproduce this? + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. See error + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Behavior + description: What should have happened? + validations: + required: true + + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain. + + - type: dropdown + id: area + attributes: + label: Area + options: + - Transactions + - Budgets + - Recurring + - Splits / Groups + - Reports + - Settings + - Auth / Login + - AI Features + - UI / Styling + - Other + validations: + required: true + + - type: input + id: browser + attributes: + label: Browser & OS + placeholder: "e.g. Chrome 124 on Windows 11" diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..6494e13 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,58 @@ +name: Feature Request +description: Suggest a new feature or improvement +title: "[Feature]: " +labels: ["enhancement"] +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What problem does this solve? Why is it needed? + placeholder: "I'm always frustrated when..." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed Solution + description: How should this work? Be as specific as you can. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Any other approaches you thought about? + + - type: dropdown + id: area + attributes: + label: Area + options: + - Transactions + - Budgets + - Recurring + - Splits / Groups + - Reports / Analytics + - Settings + - Auth + - AI Features + - Import / Export + - UI / UX + - Performance + - Other + validations: + required: true + + - type: dropdown + id: willing + attributes: + label: Would you like to work on this? + options: + - "Yes, I'd like to submit a PR" + - "Maybe, with some guidance" + - "No, just suggesting" + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..f0bfa18 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,32 @@ +## Summary + + + +## Changes + + + +- + +## Related Issue + + + +## Test Plan + + + +- [ ] `pnpm check` passes (lint + typecheck) +- [ ] Tested locally in the browser +- [ ] Schema changes: ran `pnpm db:push` successfully + +## Screenshots + + + +## Checklist + +- [ ] My code follows the project's coding conventions +- [ ] I've added no unrelated changes +- [ ] I've updated types in `src/types/` if needed +- [ ] New env vars are declared in `src/env.js` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..5cfafa2 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,41 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +## Our Standards + +Examples of behavior that contributes to a positive environment: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior: + +- The use of sexualized language or imagery and unwelcome sexual attention +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information without explicit permission +- Other conduct which could reasonably be considered inappropriate + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the project maintainer at **bugsnipper.dev@gmail.com**. + +All complaints will be reviewed and investigated and will result in a response +that is deemed necessary and appropriate to the circumstances. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), +version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..dc8c01b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,144 @@ +# Contributing to Trackit + +Thanks for your interest in contributing! This guide will help you get started. + +## Prerequisites + +- **Node.js** 20+ +- **pnpm** 10.15+ (`corepack enable && corepack prepare pnpm@10.15.0 --activate`) +- **PostgreSQL** (or a Neon/Supabase database URL) +- **Git** with conventional commits knowledge + +## Getting Started + +```bash +# 1. Fork and clone +git clone https://github.com/hasnaintypes/trackit-app.git +cd trackit-app + +# 2. Install dependencies +pnpm install + +# 3. Set up environment +cp .env.example .env +# Fill in required values (DATABASE_URL, BETTER_AUTH_SECRET, etc.) + +# 4. Push schema to your database +pnpm db:push + +# 5. Generate Prisma client +npx prisma generate --config ./prisma.config.ts + +# 6. Start dev server +pnpm dev +``` + +## Development Workflow + +### Branch Naming + +Create branches from `develop` using these prefixes: + +- `feat/` — New features +- `fix/` — Bug fixes +- `refactor/` — Code improvements (no behavior change) +- `hotfix/` — Urgent production fixes +- `docs/` — Documentation only + +Example: `feat/budget-forecasting` + +### Commit Messages + +We follow [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat(scope): add budget forecasting chart +fix(recurring): handle end-of-month clamping for Feb +refactor(router): split transaction router into sub-modules +docs: update API examples in README +``` + +**Scopes**: `schema`, `types`, `router`, `ui`, `recurring`, `budget`, `auth`, `email`, `ai`, `splits`, `settings`, `export` + +### Code Style + +- **TypeScript** strict mode with `noUncheckedIndexedAccess` +- **Prettier** formats on save (Tailwind class sorting enabled) +- **ESLint** with `consistent-type-imports` enforced +- **Pre-commit hook** auto-runs lint + format on staged files + +Run checks before pushing: + +```bash +pnpm check # lint + typecheck +pnpm format:write # auto-format +``` + +## Architecture Overview + +``` +src/ +├── app/ # Next.js App Router pages +│ ├── (public)/ # Marketing pages +│ ├── (auth)/ # Sign-in, sign-up +│ └── (features)/ # Protected app pages +├── components/ +│ ├── ui/ # shadcn/ui primitives +│ ├── forms/ # Multi-step form components +│ └── pages/ # Page-specific components +├── server/ +│ ├── api/routers/ # tRPC routers (API layer) +│ └── services/ # Business logic +├── lib/ +│ ├── inngest/ # Background jobs (Inngest) +│ ├── email/ # Email templates (Handlebars) +│ └── recurrence.ts # Recurring transaction engine +├── validation/ # Zod schemas (shared client/server) +├── types/ # TypeScript interfaces +└── constants/ # Static config and options +``` + +**Data flow**: Client → tRPC → Router → Service → Prisma → PostgreSQL + +## Key Conventions + +| Area | Convention | +| -------------- | ------------------------------------------------------------------------ | +| UI components | shadcn/ui (`npx shadcn@latest add `) | +| Path aliases | `@/*` → `src/*`, `@ui/*` → `src/components/ui/*` | +| Error handling | Use `TRPCError` in routers, not plain `Error` | +| Logging | Use `createLogger()` from `src/lib/logging/` | +| Env vars | Declare in `src/env.js` (T3 Env with Zod) | +| DB changes | Run `npx prisma generate --config ./prisma.config.ts` after schema edits | + +## Making a Pull Request + +1. Create a feature branch from `develop` +2. Make your changes with clear, atomic commits +3. Run `pnpm check` to verify lint + types pass +4. Push your branch and open a PR against `develop` +5. Fill out the PR template (description, test plan, screenshots if UI) +6. Wait for review — maintainers will respond within a few days + +### PR Requirements + +- All CI checks must pass (lint, typecheck, format) +- No unrelated changes bundled in +- New features should update relevant types in `src/types/` +- Schema changes need `pnpm db:push` verification +- UI changes should include a screenshot or recording + +## Reporting Bugs + +Use the [Bug Report template](.github/ISSUE_TEMPLATE/bug_report.yml) and include: + +- Steps to reproduce +- Expected vs actual behavior +- Browser/OS info +- Screenshots if applicable + +## Need Help? + +- Open a [Discussion](https://github.com/hasnaintypes/trackit-app/discussions) for questions +- Check existing issues before creating new ones +- Tag `@hasnaintypes` for architecture questions diff --git a/src/components/pages/(protected)/profile/edit-profile-section.tsx b/src/components/pages/(protected)/profile/edit-profile-section.tsx index 9721758..2c71950 100644 --- a/src/components/pages/(protected)/profile/edit-profile-section.tsx +++ b/src/components/pages/(protected)/profile/edit-profile-section.tsx @@ -120,7 +120,7 @@ export default function EditProfileSection() { name: K, value: string, ) => { - setFormData((prev) => ({ ...prev, [name]: value }) as FormData); + setFormData((prev) => ({ ...prev, [name]: value })); }; return ( diff --git a/src/components/pages/(public)/blog/content-section.tsx b/src/components/pages/(public)/blog/content-section.tsx index 06342c6..38ce56b 100644 --- a/src/components/pages/(public)/blog/content-section.tsx +++ b/src/components/pages/(public)/blog/content-section.tsx @@ -306,7 +306,7 @@ export const ContentSection = ({ src={src} alt={alt ?? ""} className="h-48 w-full rounded-md object-cover" - {...(rest as Record)} + {...rest} /> );