← Work

Mar 2024 – Sep 2024 · 6 months

Environmental Info CMS

I built the backend admin and RESTful API for an environmental media platform, enabling editors to manage articles, events, and subscriptions.

64
commits
47%
of codebase
6
months
6
schema changes
LaravelPHPLivewireMySQLSanctumBlade

Overview

A content management system for an environmental information media platform. I developed the admin backend CRUD functionality and all RESTful APIs consumed by the mobile app. My work covered articles, events, jobs, subscriptions, feedback, and homepage content modules.

What I Built

API Foundation & Authentication (Mar – Apr 2024)

  • Implemented API Token authentication using Laravel Sanctum
  • Article list/show API with pagination, related articles, and file attachments
  • Event list/show API with category filtering
  • Newsletter subscription and feedback submission endpoints
  • Duplicate subscription handling with proper error responses

Backend CRUD Modules (Apr 2024)

  • Article management: CRUD with categories, authors, tags, and Froala editor integration
  • Event management: CRUD with event categories and recommended events
  • Job listings, subscriber management, and feedback collection
  • Related articles feature using many-to-many pivot table

Homepage Management (Apr 2024)

  • Banner carousel CRUD with image upload
  • Highlight section editing with validation
  • Ad zone management
  • Navigation menu API for mobile app

API Refinements & Category Restructuring (May 2024)

  • Refactored tags table to subcategories for hierarchical categorization
  • Unified API response formats across all list endpoints
  • Search results API with pagination and HTML stripping
  • PageInfo SEO metadata integration in API responses
  • Multiple file attachments support for articles

Production Hotfixes (Jun – Sep 2024)

  • Fixed search API pagination and content truncation
  • Resolved Froala editor image path issues (relative → absolute URLs)
  • Corrected empty array handling for article references
  • Added page parameter support for search results pagination

Architecture Decisions

Parent ID → Pivot Table for Related Articles Original design used parent_id column on articles table for related content. This limited articles to one parent relationship. I removed parent_id and created related_articles pivot table, enabling many-to-many relationships between articles.

Tags Table → Subcategories Table The tags table was too flat for the evolving requirement of hierarchical categorization. I renamed it to subcategories and added subcategory_id to articles, allowing articles to belong to both a main category and a subcategory underneath it.

Category URI Field Removal and Re-addition Initially removed uri from categories as unused, then re-added it after API requirements clarified that frontend routing needed category slugs. This taught me to confirm API contracts before removing database fields.

Key Bug Fix: Search API Pagination and Content Processing

Problem: Search API returned all results without pagination, and content included raw HTML tags. Mobile app displayed garbled text and couldn't implement infinite scroll.

Fix: Added pagination logic in SearchResultsController with configurable page size. Used strip_tags() to remove HTML before truncating content to appropriate preview length. Added page query parameter support for frontend pagination requests.

Other Contributions

  • Soft-delete category recreation bug fix
  • City field for event location filtering
  • Menu visibility flag for categories
  • Article/event page tags display correction
  • Recommended events many-to-many relationship with timestamps
  • News headline character limit validation (12 chars max)

Reflection

Looking at my commit history, I see a pattern of schema changes that could have been avoided with better upfront planning. The tags-to-subcategories rename and the URI field removal-then-addition both happened because I didn't fully understand the frontend requirements before implementing. I've learned to push for API contract documentation before starting database design, even when timelines feel tight.