• habiting the net

    A detailed summary of technical work I delivered for HistoryPin.org, a project of Shift Collective

    At the start of 2025 I embarked on a rewrite of HistoryPin.org for Shift Collective, an Exygy Client and important place on the web where communities self-determine their stories. After being impressed with Cursor’s ability to create a meaningful contribution summary gleaned from the git commit history for SF’s Our415.org code, I let Cursor loose again. Strung together, these terse paragraphs form a pretty reasonable narrativization of my work on the rewrite. Although some categories of features are bundled a little funky – like “Development Workflow & Maintenance,” and the reductionism spurred by my instruction to “briefly summarize” clearly collapses PR descriptions to the point of omission. There’s barely a mention of the test harnessing I established with pytest, FactoryBoy, and playwright. That said, the breadth and depth of my impression on the project still feels substantial. In 9 months I drove the rewrite from greenfield to the wholesome organized entropy of near feature parity, and am proud of what I achieved with no (significant) previous experience in greenfield projects of this scope, the Django framework, or python programming. Infra, schema, frontend, backend, test harness, devx – these parts were me and I was these parts.

    Collection Management & Customization Features

    You’ve been instrumental in building out a comprehensive collection customization system. You added support for nested collections with an is_nestable field and updated forms to create collections within existing ones, leveraging query parameters for navigation. You implemented collection banner functionality including video URLs and image uploads using Django’s form utilities, along with sponsor logos with ManyToMany relationships and dropzone file uploads. You also added background color customization and visibility toggling for various collection fields, with proper permissions management for paid features.

    User Account Management & Security

    You implemented a complete account deletion system with proper cascade deletion starting from the user level, including form templating and view logic to handle both self-deletion and superuser deletion scenarios. You also worked on username logic for members, ensuring proper username creation through Google social login adapters and migrating routes to use member primary keys instead of usernames.

    Search & Discovery Functionality

    You built out member search capabilities by refactoring code to support a MembersDiscovery view with query parameter handling similar to collection searching. You implemented collection theme searching with support for multiple theme selections using comma-separated query parameters, including proper database indexing with Gin indexes for array operations. You also added location searching support to the DiscoverCollectionView with Google Place ID integration and location autocomplete functionality.

    Form Architecture & Data Handling

    You made significant improvements to form handling patterns by refactoring complex relationship management during form submission, moving more logic to model form handlers to avoid overlapping operations between views and forms. You implemented tag support for collections using Django Taggit, enabling thematic tag filters and creating reusable TagCombobox components. You also added proper permissions management for paid features, ensuring correct access controls for members and collection owners.

    Database & Performance Optimization

    Your work included several database optimizations including adding indexes on featured columns for Collections and Members, implementing Gin indexes for array searching, and optimizing deletion queries using cascades. You also worked on image handling improvements, fixing conditions that allowed setting empty pin images and implementing proper image optimization.

    UI/UX Enhancements

    You implemented responsive design patterns using CSS queries and inline JavaScript to manage UI state, particularly for collection customization forms. You created reusable components like the TagCombobox that can be used for both Pins and Collections. You also worked on template refactoring to separate page containers from list rendering logic, making the codebase more maintainable.

    Development Workflow & Maintenance

    You contributed to development experience improvements by adding seeds to database reset processes, creating new ADRs (Architecture Decision Records) addressing testing and form logic, and implementing script loading optimizations with defer and DOMContentLoaded to prevent blocking the critical path.

    You worked on paid feature integration by refactoring the Donation Block toggling to use generic relationships, removing confusing admin configurations in favor of seed scripts, and implementing CSS-based show/hide functionality for donation input fields based on toggle states.

    Code Quality & Architecture

    Your contributions emphasized better separation of concerns and reusable component design. You refactored paid features to use generic relations, created more maintainable form handling patterns, and implemented proper permission checks by comparing evaluated object IDs. You also worked on template organization to make paginated lists more flexible and reusable.

    Overall, your contributions demonstrate a strong focus on user experience, data management, search functionality, and maintainable architecture. You’ve been particularly effective at building complex features like collection customization and search/discovery systems while maintaining code quality and implementing proper security measures.

    Wednesday October 22, 2025
  • habiting the net

    A detailed summary of technical work I delivered for San Francisco's public benefits portal Our415.org

    In the fall of 2024 I joined the Consulting division of Exygy, an agency that delivers web tech solutions for civic and non-profit organizations. My very first assignment was getting a project of the Deparment of Youth and Families – Our415.org – launch-ready. Having a direct impact on families in SF was a very rad proposition, being a resident myself. Bringing a project home that’s close to home.

    In short time I completed a gaggle of technical work on Our415.org’s legacy React codebase, which had been forked from a similar benefits portal called the SF Service Guide. While pondering how I might proudly tell the tale of my work for the city to would-be interested parties like my mom or recruiters, I realized I might enlist the help of an LLM. Might Claude be able to make sense of all those commits? I don’t remember the exact instructions I put in the prompt, something like “go to and briefly summarize all the commits by author @rosschapman”. Cursor did not disappoint. It output the well-organized summations you see below, clearly extrapolating from my own characterizations of the work gleaned from commit messages and PR descriptions. And then enhancing with brand-marketing expletives.

    What surprised me most about these commits-cum-words, is the volume of accumulated work that is reflected back. It’s a lesson in the sheer mass of meaningful impressions a senior software engineer can have on a project’s formation in short time. And, perhaps, equally revelatory of how much we downplay our steady stream of achievements during a project’s speed-run to launch. To me this feels like a valuable narrativization of the private lives and material impact of senior engineers that is often relegated to archive, work diaries, 1:1 notes, as stakeholders and end-users merely avail themselves to the gestalt of these parts in production. To shouting the minutiae from the rooftops!

    Development Infrastructure & Workflow Improvements

    You were a key contributor to modernizing the development process. You implemented pre-commit hooks using Husky and lint-staged to catch lint errors before CI, significantly reducing build failures. You established Jest testing infrastructure with React Testing Library, migrating existing tests and setting up a proper testing foundation. You also configured Dependabot for automated dependency management and updated the target branch to development for better workflow integration.

    Performance Optimization & Bundle Management

    Your work focused heavily on bundle size reduction and dependency optimization. You reduced the lodash dependency burden by approximately 50% by switching to modular lodash functions instead of loading the entire bundle. You used tools like npx knip to identify and remove unused dependencies and components, including ShelterTech auth code, unused Homepage components, and WeGlot translation service code that wasn’t being used.

    Search & Map Functionality Fixes

    You addressed several critical bugs in the search and mapping functionality. You fixed incorrect marker location labels by properly moving marker label computation logic into the new transform. You resolved incorrect map markers on pages > 1 by establishing a new TransformedSearchHit view type/model that provides a canonical representation of search data with proper typing. You also removed algorithmic sorting of search results by urgency that was specific to SF Service Guide and not needed for the MVP.

    UI/UX Enhancements & Navigation

    You implemented significant navigation improvements including a new header navigation system and secondary navigation bar for listing pages. You created a SecondaryNavigationLayout component with BackNavigation functionality that uses smart routing. You also decoupled SiteSearch from Navigation and established conventions for wrapping route-level page components with secondary nav bars, including distinct mobile and desktop layouts.

    Data Handling & Error Resilience

    You improved data handling by adding proper null case handling for service.long_description and implementing optional lookups for missing image data to prevent page failures. You updated the homepage query to fetch calendar_event data and fixed date/time rendering issues. You also refactored Event/Opp card components to accommodate new calendar_event data from Strapi.

    Code Quality & Architecture

    Your contributions emphasized better component architecture and separation of concerns. You extracted the SearchResult component from SearchResults to reduce complexity and colliding terminology. You removed whitelabeling and tenant code, renaming whiteLabel to websiteConfig for clearer naming conventions. You also cleaned up old test cruft and established better naming conventions for search and map-related variables.

    Internationalization & Translation

    You worked on translation functionality by fixing Google Translate language switching issues and removing unused WeGlot translation service code. You also removed algorithmic sorting that was specific to certain tenants and not needed for the current implementation.

    Development Experience

    You contributed to developer experience improvements by adding VSCode gitignore directives and creating pull request templates. You also worked on removing technical debt and unused code that was causing confusion and maintenance overhead.

    Production & Deployment

    You updated the production build workflow with Strapi keys and worked on various fixes that required backend coordination, such as updating frontend queries to match deployed backend changes.

    Overall, your contributions demonstrate a strong focus on code quality, performance optimization, user experience improvements, and maintainable architecture. You’ve been particularly effective at identifying and addressing technical debt while implementing modern development practices and fixing complex bugs in the search and mapping functionality.

    Wednesday October 22, 2025
  • habiting the net

    Language ergonomic studies: Brevity fetish with Ruby

    Matz giving us many ways to do things.

    I want to make Ruby users free. I want to give them the freedom to choose. People are different.

    From:

    🔗 The Philosophy of Ruby: A Conversation with Yukihiro Matsumoto, Part I

    def two_lowest(numbers)
      numbers.min(2).sum
    end
    

    Enumerable methods that can receive an operator as symbol. Glacial autumn breeze whipped up from the 101. I don’t have a brevity fetish, like I know many of you do. Or the tendency to place the one-liner upon the highest of pedestal. It’s the obvious natural-language-style readability of the Ruby here that is simply remarkable.

    Achieving this is possible in JavaScript with more fanfare. But, alas, the maintenance cost of dressing up our array in Ruby’s fast casual couture.

    class NumberArray {
      constructor(numbers) {
        this.value = numbers;
      }
    
      min(n) {
    	function compareNumbers(a, b) {
    	  return a - b
       }
       this.value = this.value.sort(compareNumbers).slice(0, n);
       return this;
      }
    
      sum() {
    	function add(a, b) {
         return a + b
    	}
        return this.value.reduce(add, 0);
      }
    }
    
    function twoLowest(numbers) {
      return new NumberArray(numbers).min(2).sum();
    }
    
    
    Wednesday October 25, 2023
  • habiting the net

    Language ergonomic studies: 52 card deck

    Javascript:

    const cards = () => ['♥','♠','♣','♦']
      .map((suite) => (['2','3','4','5','6','7','8','9','10','J','Q','K','A'].map((card) => suite + card)))
    

    Clojure:

    (defn new-deck []
       (for [r [\♥ \♠ \♣ \♦]
             s [:2 :3 :4 :5 :6 :7 :8 :9 :10 :J :Q :K :A]] 
          [r s]))
    
    Sunday October 18, 2020