A placement management portal sounds like a CRUD application until you try to make one that a real college could actually use.
Students need profiles and applications. Mentors need visibility into their students. Faculty need approval workflows. Companies need drives and candidate information. Administrators need analytics and control.
Suddenly, “just CRUD” becomes roles, permissions, workflows, data relationships, eligibility rules, notifications, dashboards, and historical reporting.
That was my experience building the DigitalPlacement Portal.
The first mistake: thinking in pages
At the beginning, it is easy to think like this:
- Student page
- Company page
- Mentor page
- Admin page
- Dashboard page
But users do not experience software as pages.
They experience it as workflows.
A student creates a profile, checks eligibility, applies to a drive, receives updates, attends interviews, and eventually reaches an offer state.
A company creates a drive, defines eligibility, reviews candidates, schedules interviews, and updates results.
An administrator approves things and monitors the entire system.
The page is only the surface.
The workflow is the product.
Roles changed everything
One of the most important architectural decisions was role-based access.
The system involved students, mentors, faculty, administrators, companies, and higher-level administration.
Every role needed different capabilities.
But a role check in the frontend is not security.
If a button disappears from the UI but the API still accepts an unauthorized request, the system is not secure.
That pushed me toward thinking about authorization at multiple layers:
UI → API → Database policies
The database must protect itself even when the frontend is bypassed.
Supabase and the reality of policies
Working with Supabase made database-level authorization much more concrete for me.
I ran into policy problems that were not visible from the UI. One especially painful class of errors involved recursive policies and permissions around user and organization relationships.
The lesson was simple but powerful:
Security rules are code. Treat them with the same seriousness as application code.
A policy is not configuration you write once and forget.
It defines what the application is allowed to know and change.
Eligibility is a business rule, not a button
Placement eligibility can depend on branch, CGPA, backlogs, admission information, and company-specific criteria.
A naive implementation might simply filter a list on the frontend.
A better implementation treats eligibility as a domain rule.
That means the same logic should be understandable and enforceable wherever it matters.
It also means edge cases matter.
What happens when a student updates their CGPA after applying?
What happens when a company changes criteria?
What happens when historical eligibility needs to be understood later?
These questions taught me to think about data as a timeline rather than just current values.
Dashboards taught me about information density
I initially liked the idea of showing everything.
More cards. More charts. More numbers.
Then I realized a dashboard is not successful because it contains data.
It is successful when the right person can answer the right question quickly.
A student wants to know: “What can I apply to?”
A mentor wants to know: “Which students need attention?”
An administrator wants to know: “What is happening across placement drives?”
The same database can support all three questions, but the UI should not treat them as the same experience.
The demo that went wrong
One of the hardest lessons came from a live demonstration where a bug appeared during testing.
The presentation had been prepared. The slides were ready. The system looked good.
Then the live application did something unexpected.
That moment was painful.
But it taught me more than a successful demo would have.
A demo is a production-like environment in miniature.
If a critical flow has not been tested immediately before the demo, the slides do not matter.
Since then, I think about demo readiness as a checklist:
- fresh login
- critical workflows
- realistic data
- network conditions
- browser state
- permissions
- empty states
- failure recovery
Never trust a screenshot when you are about to demonstrate the real system.
What I learned about finishing
This project also exposed one of my recurring weaknesses: adding features faster than I close existing loops.
A project can be 95% complete and still have the last 5% contain the hardest work: exports, permissions, validation, QA, edge cases, documentation, and deployment cleanup.
The final percentage is not administrative work.
It is where a prototype becomes dependable software.
The lesson
DigitalPlacement taught me to stop measuring software by the number of screens.
A real application is a set of rules, identities, workflows, permissions, and data transitions that happen to have a user interface.
The more I build, the more I appreciate that invisible layer.
Beautiful screens get attention.
Correct systems earn trust.
I want to build the second kind.