Commit Graph

12 Commits (5c7225f077531a22346c8ab530fa4fe8b5b23fd5)

Author SHA1 Message Date
Dustin 5c7225f077 Refactor backend
* Reorganizing code into more logical modules:
  - `routes` specifically for Rocket handler functions
  - `receipts` data model for receipts
  - `transactions` for Firefly transactions
* Encapsulate database operations for receipts using the repository
  pattern; move SQL queries to external files (`sqlx` can only use
  string literals or external files for queries, not variables or
  constants)
* Remove obsolete routes, templates for old transaction-focused pages
2025-03-11 20:05:41 -05:00
Dustin 1d5bdfe920 transactions: Add JSON response format
Rocket makes it easy to dispatch requests for the same path to different
methods based on the `Accept` request header via the `format` argument
to the request attribute.

We'll use this JSON response format to populate a dropdown on the Add
Receipt form, which can be used to automatically fill the fields for
receipt data based on an existing transaction.
2025-03-11 07:49:34 -05:00
Dustin 20185bdf1f Redirect / to /receipts 2025-03-09 21:09:08 -05:00
Dustin e4ddfbd025 Run DB migrations at startup
Naturally, we need the database schema in place in order to use it.
2025-03-09 20:55:26 -05:00
Dustin da9d336817 Store receipts in the database
Rethinking the workflow again.  Requiring the transaction to be present
in Firefly already will be problematic for two very important cases:

* Gas station purchase never show up in Firefly automatically
* HSA purchase show up hours or days later and have no information
  besides the amount

These are arguably the most important cases, since they are the ones
that really need receipts in order to keep the transaction register
correct.  Thus, we need a different way to handle these types of
transactions.

Really, what I need is a way to associate transaction data with an image
I really liked the original idea of storing receipts in Paperless, but
that ended up not working out because the OCR failed miserably and thus
made it impossible to search, so finding a receipt meant looking at each
image individually.  I think, therefore, the best solution is to store
the images along with manually-entered data.

To implement this new functionality, I am using `sqlx`, a SQL toolkit
for Rust.  It's not exactly an ORM, nor does it have a dynamic query
builder like SQLAlchemy, but it does have compile-time checking of
query strings and can produce type-safe query results.  Rocket has
support for managing its connection pools as part of the server state,
so that simplifies usage quite a bit.

On the front-end, I factored out the camera image capture into an HTML
custom element, `camera-input`.  I did not update the original form to
use it, since I imagine that workflow will actually go away entirely.
2025-03-09 19:55:08 -05:00
Dustin 545baa1c36 Use Rocket's Figment for configuration
Instead of reading our own TOML file for configuration, we can hook into
Rocket's [built-in configuration system][0].  Although it doesn't matter
much right now, it may if we end up using Rocket's SQL [database
integration][1], because it uses the same mechanism.  Without making
this change, we would end up with two configuration files in that case.

[0]: https://rocket.rs/guide/v0.5/configuration/#extracting-values
[1]: https://rocket.rs/guide/v0.5/state/#databases
2025-03-09 07:07:55 -05:00
Dustin 6701579ee8 backend: Attach photo to Journal ID
Firefly attachments are related to transaction journal entries rather
than the transactions themselves.  In other words, they're attached to
splits.
2025-03-08 20:13:10 -06:00
Dustin cdf50c159c Fix path to static resources
In production deployments, the static assets are stored in
`/usr/local/share/receipts/static`.  The working directory is
`/usr/local/share/receipts`, so using a relative path of `static` is
sufficient.  We can use the same path in development with a symlink
pointing to the `esbuild` output directory.
2025-03-08 20:08:45 -06:00
Dustin d2b93bff3b Attach receipts to Firefly transactions
And now we come to the meat of the thing: the ability to update
transactions and attach receipts.  Most of this is straightforward,
except for changing the amount of split transactions.  Hopefully, this
won't come up too often, since I can't really split transactions without
a receipt.  Just to be on the safe side, attempting to change the amount
of a split transaction will return an error.
2025-03-08 18:31:46 -06:00
Dustin 0c6f9385e6 Fetch transactions from Firefly III
This is all pretty straightforward.  The only real problem is that
the search results only contain matching transactions *splits*.  Since
transactions themselves do not have an amount, the value shown in the
_Amount_ column on the transaction list may be incorrect if a
transaction contains multiple splits and some of them do not match the
search query.
2025-03-08 16:01:08 -06:00
Dustin b55fb893e2 Implement basic page navigation w/ mock data
Obviously, we'll replace the mock `Database` with a Firefly III API
client, but this is here for now to support the UI interactions.
2025-03-08 11:16:35 -06:00
Dustin 9a7b083f82 Initial commit 2025-03-05 18:02:52 -06:00