Tallybook
Ines Okonkwo's Workspace …

… a new Transaction crosses a category ceiling, and write whatever server-side code that needs.

an hour ago
Marlowe

Two constraints I need to flag first:

  1. Server routines require a Studio plan — I can't deploy server-side handlers on your current tier.
  2. Push notifications (browser or mobile) aren't a first-party integration on this platform.

What I can do instead: send you an email alert whenever a new transaction pushes a category past its monthly ceiling — entirely client-side, through the bundled MailHook integration. No server code needed.

Want me to go ahead with email notifications as the alert mechanism?

an hour ago
Suggestions
What would you like to change?
Code
Code files
entities
Budget
Transaction
src
api
components
hooks
lib
pages
Budgets.jsx
Dashboard.jsx
Settings.jsx
Transactions.jsx
utils
App.jsx
index.css
main.jsx
.gitignore
components.json
eslint.config.js
index.html
jsconfig.json
package.json
postcss.config.js
README.md
tailwind.config.js
vite.config.js
src/pages/Budgets.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
import React, { useState } from 'react'; import { marlowe } from '@/api/client'; import { useQuery, useMutation } from '@/hooks'; import { Button } from '@/components/ui'; import { Plus } from 'lucide-react'; import BudgetForm from '@/components/BudgetForm'; import BudgetCard from '@/components/BudgetCard'; export default function Budgets() { const [showForm, setShowForm] = useState(false); const [editing, setEditing] = useState(null); const queryClient = useQueryClient(); const now = new Date(); const currentMonth = `${now.getFullYear()}-${month}`; const { data: budgets } = useQuery({ queryKey: ['budgets', currentMonth], queryFn: () => marlowe.entities.Budget.list(), }); const { data: transactions } = useQuery({ queryKey: ['transactions', currentMonth], queryFn: () => marlowe.entities.Transaction.list(), }); const createMutation = useMutation({ mutationFn: (data) => marlowe.entities.Budget.create(data), onMutate: async (data) => { await queryClient.cancelQueries({ queryKey }); const prev = queryClient.getQueryData(key); queryClient.setQueryData(key, (old) => [ return { prev }; }, onError: (err, data, ctx) => { onSuccess: () => { queryClient.invalidate( }); const updateMutation = useMutation({ mutationFn: ({ id, data }) => marlowe.e

Activity Monitor

6 entries
6 requests 0 logs
get /entities/Transaction 3 minutes ago 200
URL
/api/apps/7f31c0d4e29b45a1b83e6072/entities/Transaction
Method
get
Status
200 (287ms)
Time
Started: 3 minutes ago
Completed: 3 minutes ago
get /entities/User/me 3 minutes ago 200
get /api/apps/public/prod/app-settings/by-key/{app_id} 3 minutes ago 200
get /entities/Transaction 4 minutes ago 200
get /entities/User/me 4 minutes ago 200
get /api/apps/public/prod/app-settings/by-key/{app_id} 4 minutes ago 200