Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Bug report
description: Report a reproducible xpenser problem.
title: "[Bug]: "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Thanks for reporting a bug. Please do not include secrets, API keys, or personal finance data.
- type: textarea
id: summary
attributes:
label: Summary
description: What happened?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Reproduction steps
description: List the smallest steps that reproduce the issue.
placeholder: |
1. Start the app with ...
2. Open ...
3. Click ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual behavior
validations:
required: true
- type: dropdown
id: area
attributes:
label: Area
options:
- Web app
- API
- MCP server
- Telegram bot
- Self-hosting / Docker
- Cleverbrush reference docs
- Other
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Browser, OS, Node/npm versions, Docker version, deployment mode, or other relevant details.
- type: textarea
id: logs
attributes:
label: Logs or screenshots
description: Paste relevant logs or attach screenshots. Redact secrets and personal data.
render: shell
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Questions and ideas
url: https://github.com/cleverbrush/xpenser/discussions
about: Use GitHub Discussions for open-ended questions, ideas, and Cleverbrush learning threads.
- name: Security reports
url: https://github.com/cleverbrush/xpenser/security/advisories/new
about: Please report vulnerabilities privately through GitHub Security Advisories.
45 changes: 45 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Feature request
description: Suggest a product, self-hosting, integration, or documentation improvement.
title: "[Feature]: "
labels:
- enhancement
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What user need or workflow should this solve?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
description: Describe the change you would like to see.
validations:
required: true
- type: dropdown
id: area
attributes:
label: Area
options:
- Finance workflow
- Self-hosting
- External API
- MCP server
- Telegram bot
- Cleverbrush reference example
- Documentation
- Other
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Mention any workaround, existing tool, or alternate design.
- type: textarea
id: contribution
attributes:
label: Contribution interest
description: If you want to work on this, note your intended approach or questions.
39 changes: 39 additions & 0 deletions .github/ISSUE_TEMPLATE/framework_question.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Cleverbrush framework question
description: Ask a question about how xpenser uses Cleverbrush Framework.
title: "[Cleverbrush]: "
labels:
- question
body:
- type: markdown
attributes:
value: |
For broad discussion, examples, and learning threads, GitHub Discussions is usually the best place. Use this issue form when the question points to a concrete documentation gap or unclear repository behavior.
- type: textarea
id: question
attributes:
label: Question
description: What are you trying to understand?
validations:
required: true
- type: textarea
id: context
attributes:
label: Context
description: Link the file, concept, endpoint, schema, or workflow you are reading.
- type: dropdown
id: area
attributes:
label: Framework area
options:
- Schema / contracts
- Server handlers
- OpenAPI
- Client middleware
- React forms
- Auth / authorization
- DI / ORM
- Observability
- MCP
- Other
validations:
required: true
22 changes: 22 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Summary

<!-- What changed and why? -->

## Validation

<!-- List commands, preview checks, screenshots, or skipped checks with reasons. -->

- [ ] `npm run lint`
- [ ] `npm run typecheck`
- [ ] `npm test`

## Screenshots / Preview

<!-- Add screenshots for UI changes or say "Not applicable" for non-visual changes. -->

## Checklist

- [ ] I kept the change focused.
- [ ] I updated docs or tests where needed.
- [ ] I checked for secrets, local env files, and generated build output.
- [ ] API changes keep contracts, endpoint metadata, and handlers aligned.
34 changes: 34 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Code of Conduct

## Our Pledge

We want xpenser to be a practical, respectful project for people improving the
app, learning Cleverbrush Framework, or sharing operational experience from
self-hosting it.

Participants are expected to communicate with care, assume good intent when
reasonable, and focus criticism on the work rather than the person.

## Expected Behavior

- Be respectful and direct.
- Keep discussions relevant to the project.
- Give actionable feedback when reviewing code or documentation.
- Credit others for ideas and contributions.
- Respect maintainers' time by keeping issues and pull requests focused.

## Unacceptable Behavior

- Harassment, threats, or personal attacks.
- Discriminatory language or behavior.
- Publishing private information without permission.
- Spam, trolling, or repeated off-topic comments.
- Deliberate disruption of project spaces.

## Enforcement

Maintainers may edit, hide, or remove comments; close issues or discussions;
block participants; or take other reasonable action to protect the project.

If you need to report a conduct concern, contact the maintainers privately
through GitHub.
114 changes: 114 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Contributing to xpenser

Thanks for helping improve xpenser. This repository is both a personal finance
app and a reference implementation for Cleverbrush Framework, so changes should
keep the product useful and the framework patterns easy to learn.

## Where To Start

- Use GitHub Discussions for questions, design ideas, and Cleverbrush learning
threads.
- Use issues for actionable bugs, feature requests, and documentation gaps.
- Keep pull requests small enough to review. Prefer focused product, docs,
test, or framework-reference improvements over broad rewrites.

Good first contribution areas:

- README and self-hosting improvements.
- API, MCP, and typed-client examples.
- UI polish on existing workflows.
- Tests around Cleverbrush contract, form, and handler behavior.
- Small product improvements to transaction, dashboard, vendor, or category
workflows.

## Local Setup

Requirements:

- Node.js 22
- npm 11
- Docker with Docker Compose v2

Install dependencies:

```sh
npm install
```

Create local environment settings:

```sh
cp .env.example .env
```

Build shared workspaces before starting dev servers:

```sh
npm run build -w @xpenser/contracts
npm run build -w @xpenser/client
npm run build -w @xpenser/ui
```

Start PostgreSQL:

```sh
docker compose up -d postgres
```

Start the app:

```sh
npm run dev
```

Local URLs:

- Web app: http://localhost:3000
- API: http://localhost:4000
- OpenAPI JSON: http://localhost:4000/openapi.json

## Development Workflow

Before opening a pull request, run the relevant checks:

```sh
npm run lint
npm run typecheck
npm test
```

Use focused tests for the behavior you changed. Add or update Playwright tests
when changing user-facing workflows that should be validated end to end.

The e2e suite needs a running app or deployed preview:

```sh
PLAYWRIGHT_BASE_URL=http://localhost:3000 npm run test:e2e
```

## Cleverbrush Patterns To Preserve

- Define public API shape in `packages/contracts`.
- Keep contract tree, API endpoint metadata tree, and handler tree aligned.
- Reuse named schema constants when the same shape appears in more than one
endpoint.
- Keep credential-bearing integrations behind server-side modules.
- Put tracing middleware before other API middleware.
- Prefer `ActionResult` helpers for expected API responses.

See [Cleverbrush Reference Notes](./docs/cleverbrush-reference.md) for the
current framework map and tests that guard these patterns.

## Pull Request Guidelines

- Describe the user-facing behavior or documentation outcome clearly.
- Include validation commands and any skipped checks with reasons.
- Add screenshots for visible UI changes.
- Keep generated artifacts, build output, local env files, and secrets out of
the commit.
- Do not change unrelated formatting or refactor outside the request scope.

## Security

Do not report vulnerabilities in public issues. Use the process in
[SECURITY.md](./SECURITY.md).
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Cleverbrush

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading
Loading