建置 PropHours 符合審計要求的房地產税務工時紀錄:我的經驗
What I learned building an audit-ready time log for real estate tax rules
PropHours 為美國出租物業業主打造可供審計核查的工時紀錄工具,重點是即時記錄工作並留下可信證據。系統按參與者區分工時,並在伺服器統一計算業主時數,避免把其他人的工時計入業主總數。工具亦支援跨裝置同步、會計師唯讀入口,以及透過 OAuth 讓 AI 助手讀取或新增工時紀錄。
Most time trackers are built for billing. You start a timer, stop it, and send an invoice. Nobody ever asks whether the 47 minutes you logged on Tuesday really happened.
Rental property owners in the US have a different problem. If they want rental losses to offset W-2 income, they often have to prove hours, and the proof may be read years later by an IRS examiner who assumes the log was made up after the fact. That is the problem I've been working on with PropHours, a material participation tracker for short-term and long-term rental owners.
This post covers the domain rules first, then the engineering choices that came out of them. If you build anything where the data has to hold up later (compliance, audits, expense claims), most of this carries over.
The rules, in one minute
(Not tax advice. Talk to a CPA about your own situation.)
- Material participation decides whether a rental activity is passive. There are seven tests in Treas. Reg. 1.469-5T. Two of the most used are the 500-hour test and the 100-hour test, which requires more than 100 hours and no less than anyone else, including your cleaner or property manager.
- The STR loophole: if your average guest stay is 7 days or less, the activity is generally not treated as a "rental activity" under the passive loss rules. Combine that with material participation and the losses (often boosted by depreciation) can become non-passive.
- Real estate professional status (REPS) is the long-term rental route: 750+ hours in real property trades or businesses, and more than half of your total working time.
Notice what every test has in common: a number of hours, and a question of who else worked. Courts have repeatedly thrown out taxpayers' hour claims built from after-the-fact reconstructions ("ballpark guesstimates" is a phrase that shows up in these opinions). So the product question was never "how do we count hours?" It was "how do we produce a log someone will believe?"
Engineering choice 1: capture at the moment, not at year end
The worst log is the one written in March for the previous year. So the app is built around reducing the gap between doing the work and recording it:
- One-tap timers and quick entries with sensible categories (guest communication, cleaning turnover, repairs, bookkeeping) so logging takes seconds.
- Location-based visit reminders. When you arrive at a property, the phone can nudge you to log. This needed background location on both iOS and Android, which meant writing very clear permission copy and keeping the feature opt-in.
- Calendar suggestions. Events already on your calendar can be turned into suggested entries you swipe to accept or dismiss. Nothing is logged without a human confirming it, because an auto-generated log is exactly what an examiner distrusts.
The goal is simple: the shorter the gap between doing the work and writing it down, the more believable the record.
Engineering choice 2: "who did the work" is a first-class field
Since the 100-hour test compares your hours to everyone else's, the data model can't just be user -> hours. Every entry has a participant: the owner, a spouse, a co-host, a cleaner, a property manager.
This created a subtle bug class. Early on, team members' hours could leak into the owner's totals in some views. That's the worst possible mistake for this domain, because it inflates the number the owner relies on. The rule is now enforced in one place on the server: participant hours never count toward the owner's totals. The one exception the tax rules allow, a spouse's hours for the participation tests, is handled as an explicit, separate calculation (I wrote up how spouse hours work for REPS and material participation because it confuses almost everyone).
Lesson: when a number has legal weight, compute it in exactly one place and test that place hard.
Engineering choice 3: sync that refuses to lose data
Owners log on a phone at the property and review on a laptop later, so there's an iOS app, an Android app, and a web app, all syncing to one backend.
A few things I'd do the same way again:
- The server whitelists fields. Clients can only write fields the server knows about. The cost: when you add a field on the client and forget the server, every sync fails until you ship the rule. I learned that one the hard way, and now the server rule always ships first.
- Be tolerant at the edges. Overlong titles, slightly out-of-range durations, odd avatar payloads: the server trims or clamps where it's safe instead of rejecting the whole sync. A user stuck with "sync failed" for a week is worse than a title cut at 255 characters.
- Mileage is part of the record. Drives to the property are often deductible, so each activity can carry miles and a destination, with the IRS standard rate for that year applied on export. There's a free rental property mileage log template if you'd rather use a spreadsheet.
Engineering choice 4: the output is for an accountant, not for you
The real customer of the data is often the owner's CPA. So:
- Reports are plain and boring on purpose: date, property, who did it, what was done, how long, and notes. Accountants want to scan, not admire.
- There's a read-only CPA portal where an accountant can see multiple clients and request a receipt or photo as evidence for a specific entry. The owner gets a push or email and attaches it.
- If you don't want an app at all, the material participation log template (XLSX/CSV/PDF) uses the same columns.
Engineering choice 5: an MCP server, because people ask their assistant now
Some users would rather ask "how many hours do I have on the lake house this year?" in ChatGPT or Claude instead of opening an app. PropHours exposes an MCP endpoint so an AI assistant can read your log (and add entries you dictate) through OAuth. Two rules I followed:
- Reads are scoped to the signed-in owner's own data.
- Entries added through an assistant are marked with their source, and the assistant is told to confirm real work details and never invent hours, so the log still shows what was typed by a human versus dictated through an AI.
What I'd tell someone building in a compliance-heavy niche
- Read the primary sources. I keep the IRS publications (Pub 925, Pub 527, Form 8582 instructions) open while writing features and docs. Blog summaries get details wrong constantly.
- Design for the skeptical reader. Ask "would an examiner believe this?" before "is this convenient?"
- Give away the simple tools. The STR loophole calculator and the free templates help people decide whether the rules even apply to them, before any sign-up.
If you own a rental or two and want to try it, PropHours is on iOS, Android and the web. If you're building something similar, I'm happy to compare notes in the comments.
來源:DEV Community · dev.to