Case study · Platform · Non-profit
Avery & Aubrey's Way Portal
A document portal for a non-profit, inherited from a previous vendor with no source code, security gaps, and uploads that silently failed. Hardened in place instead of rewritten.

The problem
The organization helps families apply for assistance programs; applicants upload documents, and administrators review them. The previous vendor had left. What remained was a compiled JAR on a single VM, a database, and a front end. There was no repository. Files over one megabyte failed to upload with no error. Access control and the API surface had gaps that a written review documented in detail.
My role
HausHive took over as developer of record. I did the review, the recovery of a buildable codebase, the security fixes, the infrastructure hardening, the deploys, and the client communication. Every change was framed as ours to fix, with the client owning the decisions that needed her account access.
What I built
- A buildable source tree from the shipped artifact. Decompiled the JAR, fixed the seven places the decompiler produced code that would not compile, and made the result boot identically to production. The most surprising break was parameter names: the decompiled build preserved names like
str2, which broke Spring's name-based binding, so every path and query parameter got an explicit name. - Authentication and authorization fixes. Moved sessions to httpOnly cookies with a transition path, rewrote the security configuration, and added role and ownership checks across the API, with responses shaped so records and accounts cannot be enumerated.
- Edge and OS hardening. The edge now denies everything on the API that is not explicitly public, hides internal surfaces, rate-limits authentication, and enforces the upload cap that fixed the silent failures. The service runs as a dedicated user under a sandboxed unit with locked-down configuration.
- Admin promotion and audit. Promote and demote endpoints with guards against self-demotion and removing the last admin, an admin roster, and an append-only audit log table with its own read endpoint.
- Generic document categories. New upload types are now a single row insert; the front end renders unknown categories generically, so the client adds a category without a deploy.
Architecture
Request path: browser to nginx gate to Spring Boot service under systemd to MySQL, all on one VM.
Difficult problems
Rebuilding without source. The decompiled project compiles and boots equivalently to the production JAR only after fixing lambda parameter shadowing, raw generic collections, and a constant the decompiler had turned into a reference to a class that did not exist. The build is now trusted enough to deploy from.
The 29-hour outage. The inherited machine lost its network under resource pressure while the cloud console still reported it healthy. Recovery had to preserve the public address, because DNS pointed at it, which ruled out the obvious fix. Resource limits and monitoring followed so it cannot fail silently again.
An unexpected account found mid-deploy. While retiring the previous vendor's access, an administrator account nobody recognized turned up, created through one of the gaps being closed at that moment. It was removed in the same change, and every admin change is now recorded.
// Ownership check on file reads: 404, never 403, so IDs cannot be probed
public FileDTO getById(Long id, User caller) {
return repo.findById(id)
.filter(f -> f.ownerId().equals(caller.id()) || caller.isAdmin())
.map(mapper::toDto)
.orElseThrow(NotFound::new);
}Decisions and tradeoffs
- Harden in place rather than rewrite. The organization needed the portal working next week, not next quarter. A rewrite would have reintroduced every edge case the old code already handled.
- Transition mode for sessions. The backend accepts cookie or bearer while the front end migrates, so nothing broke for users mid-change.
- The client owns credentials. Mail rotation, cloud IAM, and account confirmations were framed as the client's actions with a written handover, not done quietly on her behalf.
