- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
Building a Staff App for Property Teams: Design for the Basement, Not the Desk
About Post
Most business software is designed by people sitting at desks, for people sitting at desks. Big screen, keyboard, stable Wi-Fi, a cup of coffee and time to read.
A property team's day looks nothing like that. A technician is in a plant room two floors underground with one bar of signal. A leasing officer is walking a prospective tenant through an empty unit. A supervisor is approving work between two site visits, phone in one hand, keys in the other.
Kate PMS, the property management system I work on, has a web portal, a tenant app and a staff app. The staff app is the one that has to survive that kind of day. These are the principles I think matter most when building for people in the field, described in general terms rather than as a tour of a live system.
1. Design for the context, not the screenshot
A screen that looks clean in a design review can be painful in a stairwell. The questions that matter are physical:
- Can it be used with one hand, while the other holds a torch or a ladder?
- Are the buttons big enough for a quick, imprecise tap?
- Is it readable in bright sunlight on a roof or in a car park?
- Can the main task be done in a few taps, without typing paragraphs?
That last one changes forms the most. On a desk, a free-text description is fine. In the field, a photo, a short list of categories and an optional note do the same job faster and give you cleaner data. A camera is the best keyboard a phone has.
2. Treat signal as something you can't count on
Full offline support is a big engineering commitment: local databases, sync engines, conflict resolution. Many apps don't need all of it. But every field app needs to be offline-friendly, which is a much smaller and very achievable set of habits:
- Show the last known data instead of an empty spinner. A job list from ten minutes ago is far more useful than a loading screen.
- Never lose what the user did. If they marked a job as done and attached three photos, that action must survive a dropped connection, an app switch and a phone that goes to sleep.
- Retry safely. A write that's retried must not create duplicates. That's exactly what idempotency keys are for: the app generates a key per action and the server ignores repeats.
- Upload big things separately. Photos and videos should upload in the background and retry on their own, without blocking the small, important status change.
- Be honest about state. "Saved on this phone, waiting to sync" is a perfectly good message. Pretending something was sent when it wasn't is how trust in an app disappears.
The field rule: the user's action is sacred. Whatever the network does, the work someone did on site must never silently vanish, and must never be recorded twice.
3. Avoid conflicts by design, not by algorithm
The hard part of offline work is two people changing the same thing at once. Clever merge logic is one answer. A simpler one is to design the workflow so conflicts rarely happen: each task has one clear owner at a time, status changes move in one direction, and comments and photos are added rather than edited.
When the data model makes "two people overwrite each other" unlikely, the sync problem becomes much smaller.
4. Permissions decide what the app even is
A staff app isn't one app. It's a slightly different app for every role. A technician needs their assigned jobs and nothing else. A supervisor needs their team's work and approvals. Finance needs payment information that a technician should never see.
Two principles make role-based access work on mobile:
- Show only what the role needs. Fewer menus means a faster, simpler app, and fewer chances to tap the wrong thing. Good permissions are a UX feature, not just a security one.
- Enforce everything on the server. Hiding a button in the app is presentation. The API must check every request against the user's role and scope, because anything the app can call, someone else can call too.
5. Notifications should be few, specific and actionable
Push notifications are the easiest way to make a staff app useful and the fastest way to make it ignored. If every comment, update and system event buzzes the phone, people mute it, and then they miss the urgent one.
- Notify about things that need this person to act: a new assignment, an approval, an urgent request.
- Deep-link straight to the item, not to the home screen.
- Treat the notification as a hint. When the app opens, fetch the current state from the API, because the job may have changed since the notification was sent.
6. One API, many clients
The staff app, tenant app and web portal all look at the same contracts, payments and maintenance requests. They should all talk to the same API, with the same validation and the same business rules. If the mobile app has its own copy of the rules, sooner or later the web portal and the app will disagree about what's allowed, and you'll find out from a confused user.
Keeping that API backwards compatible matters more on mobile than on the web, because you can't force everyone to update their app the moment you deploy.
7. Watch someone use it
The best feedback for a field app doesn't come from a ticket. It comes from watching a real user try to do their job with it, in the real place they do it. You'll learn more from one awkward moment on site ("where's the button to add another photo?") than from a week of guessing at a desk.
What I'd tell anyone building one
- Design for one hand, bright light and little time.
- Be offline-friendly even if you're not fully offline.
- Never lose an action; never record one twice.
- Let roles shape the app, and enforce them on the server.
- Notify less, and make every notification actionable.
If you've built an app for people who work away from a desk, what was the design assumption that broke first once it met the real world?

Be first to comment it...