Retiring this series
Moving forward I’ll be putting all updates regarding this project in the projects section, located here: /projects/course-manager/
Moving forward I’ll be putting all updates regarding this project in the projects section, located here: /projects/course-manager/
Major milestone today. After 2 months I finally deployed a full rewrite with no issues. I expected to have all kinds of problems because I made such huge changes, in addition to restructuring everything, but miraculously everything went smoothly. It’s nice to be surprised in that way instead of the other way, which is a good case for being pessimistic 😅 One major change I made is I now build one site per course rather than one site per user. Now you can give students a URL and that’s only the course they’re taking and no others. Now I need to figure out a way to limit the number of course sites that can be built or it will get out of control very quickly with multiple users. ...
I’m finally wrapping up my rewrite, after 2 months of work, which was a lot longer than I thought. Ultimately I’m glad I did it, as everything feels a lot easier to understand and I’ll have a much better time adding new features and fixing bugs moving forward. It took longer partly because I was also improving things, naturally. Actually, this was much more than a rewrite, come to think of it. I replaced my own static site generator with Hugo and that took a ton of time. I suppose this is the danger of rewrites. It’s never just a rewrite. ...
I decided to try once again to replace my own site generator with Hugo. If you read previous posts you’ll remember that I tried that a while back and found the task pretty daunting and ultimately not worth the benefits. But I had been using Hugo for several small projects, like my podcast site, my family site, my district Python PLC site, and my portfolio site… and after becoming more familiar with its features, and coming to appreciate how powerful of a system it is, I realized that, however big the investment might be in time, it would probably be worth it if I am able to integrate it with my project. ...
Today I decided to put my file system and markdown rendering functions in the infrastructure layer; my thinking was to push these low-level concerns as far down as possible and avoid having the handler or services do file system things at all costs. Got the file system functions working nicely with tests, and wrote the service to use a filesystem interface satisfied by these functions. Focusing on Terms handler, there is a lot left still, but I left for home on a good note: showFiles will actually display the files. All of the URLs on that page are currently empty, probably due to not being registered (so far I have only registered the showFiles route handler). ...
Progress has been a little slow due to other life events. Spent 2 weeks on Reserve annual training 13-26 April, plus getting self and family ready for it and recovering from it has been somewhat of a strain. There were a couple of periods lasting several days in which I didn’t get a chance to touch the project. It’s amazing how quickly you can lose the mental picture, even after such a short time. Everything looked completely foreign to me each time I had gone a few days without looking at it. ...
Today I began a complete rewrite. Things are starting to feel unweildy and I would like to conform with modern architectural practices to the extent feasible. I would like to maximize the maintainability of my codebase because I have come to think that perhaps it is much much harder to add features or fix bugs than it probably should be. I am really starting to dislike the hacky way that I wrote things in the beginning and want to make it all nice and neat. ...
Today I made an amazing accidental discovery. If html is wrapped in an iframe then the browser nav buttons like 🔙 will work even though the URL isn’t modified. This means I can essentially navigate between html-rendered markdown files while staying on the current page! For example, in a lesson assignment’s file I put a link to a unit project file. I was amazed to see the new file simply replace the previous file in the iframe. This will be extremely useful. ...
Summary Spent yesterday working on the course assessments page. Filter and sort functionality seems to be working and it seems actually useful and not merely impressive. Change log created I began a change log as well as a sub-directory for changes. For what follows I’ve created a pending change. I’ve been wrestling with how to conceive of the assessment entity. Currently it has a mandatory lesson_id field and this is the only thing linking it to a course let alone a user. The good part about that is most assessments are tied to a particular topic, and should be given on the day that topic is covered. So currently if a lesson is assigned to a different date, the assessment goes with it. NOTE: that said, the assigned and due dates are not currently updated accordingly! But we could make that an optional attribute and still retain that functionality. Sometimes it’s more appropriate to tie an assessment to a unit or course rather than a specific lesson. So the mandatory field should be the course_id, and then we could have optional fields for unit_id and lesson_id. if a lesson is moved and it has an assessment associated with it, the assessment will be moved too (again however, see previous note regarding assigned and due dates!). Canvas integration? I’ve been toying with some level of integration with Canvas via their API. Some thoughts on this topic: Charlotte-Mecklenburg Schools is transitioning to Infinite Campus as an administrative system. I don’t know if this replaces Powerschool, Canvas, or both, but I should find out before investing substantial time and energy into an integration with either of these systems. I’ve played with the API and it’s quite easy to get started with. As a tentative first step, I could allow for the creation of assignments so that they could be created once in Course Manager and then modified as needed in Canvas. Anecdotally, this would be quite a help actually in my own daily workflow as a teacher. Eventually could try to sync them so that changes to an assessment would be reflected in the corresponding Canvas assignment, but this could turn out to be a very tough, or at least a very labor-intensive problem, so I should look thoroughly and at least 10 times before I leap on that. Feature: Content generation with LLM? I’ve also been toying with the idea of integration with LLMs, mainly for example suggesting slide content. This would not necessarily be a very tall order, but two big questions come up: 1. $$ and 2. how much value am I providing with such a feature, considering the user could just get similar functionality with a chat interface and copy-paste. The main thing I think a typical user would not know how to do (although it’s very easy to teach) is providing the proper context, for example the format for the slides. It might be better to just educate the user on for example how to use AI for generating markdown slides.
Today I made a big change, assessment category is now a string instead of an integer. this meant doing a database migration and converting all ints to equivalent strings. I did my first go migration with goose, as up til now I had only done sql migrations. The conversion logic required more than I could do with sql alone. Important: migrations are now included in the deployment pipeline in the following way: Migration is included in app image build (Dockerfile.echo) In task run-prod migration is run as a separate container