[{"data":1,"prerenderedAt":435},["ShallowReactive",2],{"blog-staff-attendance":3,"blog-related-staff-attendance":157},{"id":4,"title":5,"author":6,"body":7,"category":141,"date":142,"description":143,"draft":144,"extension":145,"featured":146,"image":147,"imageAlt":147,"meta":148,"navigation":146,"ogImage":147,"path":149,"seo":150,"stem":151,"tags":152,"updated":147,"__hash__":156},"blog\u002Fblog\u002Fstaff-attendance.md","Your school knows who was in class. Does it know who was teaching?","team",{"type":8,"value":9,"toc":129},"minimark",[10,14,17,20,23],[11,12,13],"p",{},"Most schools know exactly who was in class yesterday, and only roughly who was teaching.",[11,15,16],{},"The pupils' register is taken every morning by a teacher who has to be there anyway, and it is filed\nin a system. Staff attendance is a hardback book on the front desk, signed on the way past, with a\ntime column filled in from memory and a month that gets added up only when somebody asks.",[11,18,19],{},"Nobody chose that. It is just what is left when one register has a natural moment and the other does\nnot.",[11,21,22],{},"1410SMS now records staff attendance the way it records everybody else's. Most of the design is in\nwhat it refuses to do.",[24,25,30,35,38,41,44,48,51,54,57,61,64,72,75,78,82,85,88,92,95,98,101,105,108,111],"screenshot",{"alt":26,"height":27,"src":28,"width":29},"The staff attendance board for a school day: counts of clocked in, late, not in yet and absent across the top, then a table of every staff member with their status, first clock-in time, whether they are on site, hours worked so far, and anything needing checking",1456,"\u002Fdocs\u002Fstaff-attendance\u002Fboard.png",1832,[31,32,34],"h2",{"id":33},"it-is-a-punch-log-and-nothing-about-a-day-is-stored","It is a punch log, and nothing about a day is stored",[11,36,37],{},"Staff clock in and clock out. Those are appended, and nothing else is written.",[11,39,40],{},"Whether a day counts as present, late, absent or closed is worked out when somebody reads it, from\nthe punches and the school's own settings. Nothing stores the verdict.",[11,42,43],{},"The reason is drift. Store \"3 September: present\" and you have created a record that can disagree\nwith the punches it came from, and then somebody has to decide which one is right. Derive it and\nthere is one answer, and correcting a punch corrects everything downstream of it in the same moment.",[31,45,47],{"id":46},"absence-is-derived-and-never-entered","Absence is derived and never entered",[11,49,50],{},"A staff absence is no clock-in, on a working day, that nobody was excused from.",[11,52,53],{},"There is no absent button, so nobody marks a colleague absent and, more to the point, nobody forgets\nto. The board, the timesheet, the absence report and the morning reminder all ask the same question\nof the same data, so no two of them can disagree about who was in.",[11,55,56],{},"Each school's own digest goes out at its own 07:00, off an hourly tick, rather than at one time that\nis the morning in Lagos and the middle of the night somewhere else.",[31,58,60],{"id":59},"verification-is-configuration-and-a-check-with-no-implementation-fails","Verification is configuration, and a check with no implementation fails",[11,62,63],{},"Schools do not agree on what proves somebody arrived. Some want a photograph, some a location, some\na shared device on the desk, and some are perfectly happy with a tap.",[11,65,66,67,71],{},"So the verification chain is per-school. With one rule: ",[68,69,70],"strong",{},"a required check that has no\nimplementation fails rather than passes."," A security control that quietly degrades into a green\ntick is worse than not having one, because the school believes it is switched on.",[11,73,74],{},"Five preconditions cannot be switched off by anybody: three of them can refuse a punch (a location\nreading too vague to prove anything, a faked location, a second tap moments after the first) and two\nonly record what they found (whether the school was down as closed that day, and how far the\nhandset's own clock was from ours).",[11,76,77],{},"Alongside them, one phone is bound to one member of staff per school, which closes buddy-punching\nwithout a fingerprint reader, a turnstile or anybody's face. Per school rather than outright,\ndeliberately: somebody teaching at two schools carries one handset, and the second school has no\nbusiness being told the first has it.",[31,79,81],{"id":80},"no-background-location-and-the-reminder-says-only-what-a-clock-knows","No background location, and the reminder says only what a clock knows",[11,83,84],{},"The mobile app does not use background location. Not as a setting, not as an option a school can\nturn on. It is forbidden in the client and a test enforces it.",[11,86,87],{},"The morning reminder is therefore a clock, and the wording is a clock's: it is ten past eight and you\nhave not clocked in yet. It does not say \"you appear to be at school\", because it does not know that\nand will not imply it. A staff attendance feature that tracks where teachers are on a Saturday is a\ndifferent product, and not one we want to sell.",[31,89,91],{"id":90},"the-one-we-got-wrong-first","The one we got wrong first",[11,93,94],{},"A recorded school closure used to refuse a staff punch. It reads as obviously correct: the school is\nshut, so nobody is clocking in.",[11,96,97],{},"It is wrong, and a school found out for us. Staff work when the pupils are away. Marking, planning,\nadmissions, the fortnight before a term resumes. A school that had dated its terms honestly found\nitself locked out of its own timesheet for the whole of the long vacation.",[11,99,100],{},"A closure now records the punch and still derives the day as closed. The minutes count, so the\ntimesheet is right. The day-present does not, because the denominator for punctuality is the days the\nschool was actually open.",[31,102,104],{"id":103},"leave-deliberately-unfinished","Leave, deliberately unfinished",[11,106,107],{},"Leave is two inclusive dates and a kind the school defines. There is no approval workflow.",[11,109,110],{},"Approvals, shift patterns and payroll belong to a workforce module, and half of one embedded in\nattendance would have to be unpicked later. What matters is that the deferral is safe: the timesheet\nexport already carries every segment's exact in and out timestamps, so any rounding or approval policy\ncan be computed from data that exists today rather than needing a year of history nobody kept.",[24,112,116,120,123,126],{"alt":113,"height":114,"src":115,"width":29},"The Staff leave panel, headed with a line saying recorded leave silences the absence digest and is reported apart from absence on the timesheet, and buttons for Kinds and Record leave. Three records are listed: Chidi Okafor, Training, 17 to 19 August 2026, 3 days, curriculum workshop in Abuja; Emeka Johnson, Official duty, 12 August 2026, 1 day, WAEC marking centre; and Amina Yusuf, Medical, 10 to 14 August 2026, 5 days, surgery recovery. Training and Official duty carry a green badge and Medical a grey one.",606,"\u002Fdocs\u002Fstaff-leave\u002Fleave.png",[31,117,119],{"id":118},"what-it-looks-like-day-to-day","What it looks like day to day",[11,121,122],{},"The web has a six-tab attendance workspace covering pupils and staff together, and any one of six\npermissions opens it, with each tab gating itself. So a class teacher with the register permission\ngets the register, and an HR officer with only the staff keys still reaches the page rather than\nbeing turned away at the door.",[11,124,125],{},"The phone carries both halves: a member of staff clocks in from it, and an administrator gets the\nboard, the timesheet and the leave list, built from the permissions they actually hold.",[11,127,128],{},"The four time settings ship with ordinary defaults, and clearing a box is a real answer rather than an\nempty one. It means \"follow the working hours I have already given you\", which is the fallback for a\nschool whose day is not the usual one.",{"title":130,"searchDepth":131,"depth":131,"links":132},"",3,[133,135,136,137,138,139,140],{"id":33,"depth":134,"text":34},2,{"id":46,"depth":134,"text":47},{"id":59,"depth":134,"text":60},{"id":80,"depth":134,"text":81},{"id":90,"depth":134,"text":91},{"id":103,"depth":134,"text":104},{"id":118,"depth":134,"text":119},"Operations","2026-08-16","The pupils' register is taken every morning. Staff attendance is a signing book on the front desk. Here is how we built the second one, and the four things we deliberately refused to do.",false,"md",true,null,{},"\u002Fblog\u002Fstaff-attendance",{"title":5,"description":143},"blog\u002Fstaff-attendance",[153,154,155],"attendance","staff","product","P7wNggfK4sbL-qoOrUGIVRv-vHMyK27k702JvZ1B-s0",[158,320],{"id":159,"title":160,"author":6,"body":161,"category":141,"date":142,"description":311,"draft":144,"extension":145,"featured":144,"image":147,"imageAlt":147,"meta":312,"navigation":146,"ogImage":147,"path":313,"seo":314,"stem":315,"tags":316,"updated":147,"__hash__":319},"blog\u002Fblog\u002Fexams-workspace.md","Nobody should draw an exam timetable in pencil",{"type":8,"value":162,"toc":305},[163,166,169,173,176],[11,164,165],{},"The exam timetable is drawn on paper, in pencil, by one person, in a week that nobody else wants.",[11,167,168],{},"Then a teacher goes on leave, one paper moves to the Thursday, and the whole grid needs checking\nagain by eye. Usually it is not checked, because checking it means reading forty rows against each\nother twice. So a class sits two papers at once in the third week, and everybody finds out in the\nhall.",[31,170,172],{"id":171},"a-series-checked-before-it-goes-out","A series, checked before it goes out",[11,174,175],{},"An exam series in 1410SMS is a set of sittings: a class, a subject, a date, a time, a room, an\ninvigilator. Building one is ordinary data entry. What makes it worth having is what happens next.",[24,177,181,187,193],{"alt":178,"height":179,"src":180,"width":29},"The Exams page with four tabs across the top, Exam Series, Builder, Reports and Settings, with Builder selected. To the right of the tabs an exam picker reads First Term Examination 2026\u002F2027, followed by a draft badge and the label Terminal Examination. Below, the series heading gives its term, session and dates beside a Publish and notify button; then a panel headed Worth checking before you publish, listing three amber Check findings and reading 0 to fix, 3 to consider; then the Generate the timetable panel, open at step one of four, Who is sitting.",1416,"\u002Fdocs\u002Fexams-workspace\u002Fworkspace.png",[11,182,183,186],{},[68,184,185],{},"One action checks the whole series."," It reports every clash it can find, including the two that\nmatter most: the same class sitting two papers at once, and the same invigilator in two halls at\nonce. Clash detection runs on the weekly timetable engine's own logic rather than a second\nimplementation of it, so the two cannot drift apart and start disagreeing about what a conflict is.",[11,188,189,192],{},[68,190,191],{},"Publishing runs the same check and refuses on errors",", with the findings on the response rather\nthan a shrug and a support ticket. You cannot publish a broken series by accident.",[24,194,198,202,205,217,221,224,231,235,238,245],{"alt":195,"height":196,"src":197,"width":29},"A panel headed 'This timetable cannot be published yet' at the top of an exam page for First Term Examination, First Term 2026\u002F2027, dated 22 to 24 July 2026. It lists eleven findings, with '1 to fix, 10 to consider' on the right. The first carries a red Fix badge and reads that JSS 1A's Computer Science paper is on 2026-07-24, a day the school calendar says it is closed. Below it, amber Check badges list seven subjects JSS 1A takes that have no paper in the exam, and three papers with no invigilator.",936,"\u002Fdocs\u002Fexam-validation\u002Ffindings.png",[31,199,201],{"id":200},"publishing-is-its-own-permission","Publishing is its own permission",[11,203,204],{},"Building a draft and telling four hundred families are not the same act, so they are not the same\npermission. A member of staff can be given the series to build and not the button that sends it.",[11,206,207,208,211,212,216],{},"This pairs with the rule that makes drafts usable at all: ",[68,209,210],{},"a draft announces nothing."," Move papers\naround in a draft as much as you like and the world stays quiet. Move or drop a paper ",[213,214,215],"em",{},"after","\npublication and that class's families are told, because they have already written the old date in a\ndiary.",[31,218,220],{"id":219},"several-papers-move-together","Several papers move together",[11,222,223],{},"A cascade is the normal case. The Chemistry paper moves, so the Physics paper has to move to make\nroom, so the room booking changes.",[11,225,226,227,230],{},"Moving them one at a time through a clash checker means passing through arrangements that are not\nvalid and being told so at each step, which teaches you to ignore the checker. So a bulk move takes\nthe whole proposal and checks it against the series ",[68,228,229],{},"as it would be",", not as it is.",[31,232,234],{"id":233},"a-whole-series-can-be-generated","A whole series can be generated",[11,236,237],{},"If you would rather not place forty papers by hand, the workspace will do it, using the same\nconstruction core the weekly timetable generator uses.",[11,239,240,241,244],{},"You describe the shape you want, under ",[68,242,243],{},"Settings → Examinations",", rather than tuning six numeric\nweights: balanced, spread out, finished quickly, or mornings first. That distinction is most of the\nreason the feature is usable, because a scheduler that asks a bursar to balance six weights is a\nscheduler that gets used once. The weights are still there, behind a Custom option, for the school\nin fifty that wants them.",[24,246,251,255,258,261,265,281,284,288,291,298,302],{"alt":247,"height":248,"src":249,"width":250},"Step three of the generation wizard, What is in the way, with the four steps shown as pills reading Who is sitting, Which days, What is in the way and How to weigh it. Under a line saying what the engine needs in place, checked against this exam and the classes named above, a Re-check button sits on the right. The verdict reads Ready, with 1 thing worth knowing, above an amber note that JSS 1B has no pupils on its roll so no room can be checked against its size, and Back and Next buttons below.",542,"\u002Fdocs\u002Fexam-timetable-generation\u002Fgenerate.png",1754,[31,252,254],{"id":253},"a-paper-can-be-the-online-test-that-is-that-paper","A paper can be the online test that is that paper",[11,256,257],{},"If a subject is examined on the computer-based testing module, the sitting can be linked to that\ntest. The sitting then owns the test's window and its class list, so there is one thing to keep\ncorrect rather than two that must be kept in step.",[11,259,260],{},"On the phone that paper carries an \"Online\" tag, ahead of the room, which is still shown beside it.",[31,262,264],{"id":263},"four-documents-all-of-them-printable-from-a-phone","Four documents, all of them printable from a phone",[266,267,268,272,275,278],"ul",{},[269,270,271],"li",{},"A class's papers, for the noticeboard and the parents.",[269,273,274],{},"An invigilator's list, so they know their duties.",[269,276,277],{},"A room's day, for whoever is running that hall.",[269,279,280],{},"The attendance roster a paper is registered on.",[11,282,283],{},"All four print from the mobile app as well as the web, which is not a box-ticking exercise. An\ninvigilator wants their roster on the way into the hall, not at a desk twenty minutes earlier, and\nthat is the whole reason it is on a phone.",[31,285,287],{"id":286},"one-naming-decision","One naming decision",[11,289,290],{},"Internally the object is a \"diet\", which is what examination boards call a round of exams.",[11,292,293,294,297],{},"Every screen a school reads calls it an ",[68,295,296],{},"exam series",", because \"diet\" is a word that costs a bursar\nthirty seconds and teaches them nothing. The technical term survives in our code and nowhere a\ncustomer looks.",[31,299,301],{"id":300},"what-stayed-on-the-web","What stayed on the web",[11,303,304],{},"Generation, the module's settings, linking a CBT test, and cloning a series or building it a class at\na time are web-only, deliberately. They are the parts done sitting down, once, with a spreadsheet\nopen. Everything done standing up, in a corridor, in the week of the exams, is on the phone.",{"title":130,"searchDepth":131,"depth":131,"links":306},[307,308,309,310],{"id":171,"depth":134,"text":172},{"id":200,"depth":134,"text":201},{"id":219,"depth":134,"text":220},{"id":233,"depth":134,"text":234},"One person draws the exam grid, one paper moves, and the whole thing needs checking again by eye. Usually it is not. Here is the workspace that replaced the pencil.",{},"\u002Fblog\u002Fexams-workspace",{"title":160,"description":311},"blog\u002Fexams-workspace",[317,318,155],"exams","timetable","jFxF93HEcP_aRPykpnno8RN7mJtKB84r5Q-_-kMGy9o",{"id":321,"title":322,"author":6,"body":323,"category":425,"date":142,"description":426,"draft":144,"extension":145,"featured":144,"image":147,"imageAlt":147,"meta":427,"navigation":146,"ogImage":147,"path":428,"seo":429,"stem":430,"tags":431,"updated":147,"__hash__":434},"blog\u002Fblog\u002Fright-to-left-text.md","The bug that printed confident nonsense",{"type":8,"value":324,"toc":418},[325,328,331,335,338,341,344,348,351,357,363,369,372,376,379,382,390,394,399,402,406,409],[11,326,327],{},"A school sent us a report card and asked why the Arabic subject names came out as nonsense.",[11,329,330],{},"They were not nonsense. They were confident, well-spaced, correctly-kerned Latin letters, printed\nneatly in the place where Arabic should have been. That distinction is the whole story, because it is\nwhat made the problem hard to see from our end. It did not look like a rendering failure. It looked\nlike a school that had typed something wrong.",[31,332,334],{"id":333},"why-a-pdf-does-this","Why a PDF does this",[11,336,337],{},"The fonts built into the PDF standard are WinAnsi-encoded. They cover Latin and not much else.",[11,339,340],{},"Hand one of them Arabic and it does not draw a box, and it does not refuse. It takes each byte, maps\nit to whatever Latin glyph sits at that position in its own encoding, and draws that, at full\nquality. The output is a finished-looking document that nobody at the school can read.",[11,342,343],{},"A missing-glyph box would have been a better outcome. A row of boxes is obviously broken and gets\nreported on the first day. Plausible-looking Latin gets filed, and the school assumes the fault is\ntheirs.",[31,345,347],{"id":346},"three-separate-problems","Three separate problems",[11,349,350],{},"Getting Arabic onto the page needs three things, and skipping any one of them still produces a wrong\ndocument rather than an obviously broken one.",[11,352,353,356],{},[68,354,355],{},"A font that has the glyphs."," Without an embedded face that actually contains Arabic, you are back\nto the Latin substitution above.",[11,358,359,362],{},[68,360,361],{},"Shaping."," Arabic letters change form depending on what sits either side of them: initial, medial,\nfinal, isolated. Draw the isolated forms in sequence and you get disconnected letters. A reader can\ndecode it, in the way you can decode a word with the letters spaced out, and nobody would accept it\non a document their child brings home.",[11,364,365,368],{},[68,366,367],{},"Bidirectional ordering."," The shaper does not do this, which is the part most often missed. A line\nthat mixes Arabic with a pupil's Latin name or a numeric mark has to have its runs put in the right\norder first, and then the glyphs inside each run ordered by the shaper. Get it wrong and the mark\nends up on the wrong side of the subject it belongs to.",[11,370,371],{},"So the order is: work out the run order, then let the shaper order what is inside each run.",[31,373,375],{"id":374},"where-we-put-the-fix","Where we put the fix",[11,377,378],{},"At the single point where the platform creates a PDF document, not in each renderer.",[11,380,381],{},"A renderer that has to opt in to correct text is a renderer somebody eventually forgets, and the one\nthey forget is the certificate. Patching the one place a document is created means every PDF that\nlibrary draws got this at once: invoices, receipts, the family's own copies of both, the exam\ntimetable and our own subscription receipt.",[11,383,384,385,389],{},"Four of our documents render through headless Chromium rather than the PDF library, and they needed\nthe other half of the same problem solved: an inlined Arabic face, and ",[386,387,388],"code",{},"unicode-bidi: plaintext"," on\nthe elements that hold a school's own words. Those are the ones whose direction we cannot know in\nadvance, because they are whatever the school typed.",[31,391,393],{"id":392},"the-bar-for-shipping-it","The bar for shipping it",[11,395,396],{},[68,397,398],{},"A school with no Arabic gets byte-identical documents to the ones it got before.",[11,400,401],{},"That was the condition. A change to the text engine underneath every document the platform produces\nis exactly the sort of thing that shifts a margin by a point, re-wraps a line on someone's invoice,\nand turns into a fortnight of reports from schools who have nothing to do with Arabic.",[31,403,405],{"id":404},"if-your-school-teaches-arabic","If your school teaches Arabic",[11,407,408],{},"Nothing to switch on. Type Arabic into subject names, teacher remarks, class names or the head\nteacher's comment and it prints properly, mixed with Latin and with numbers on the same line.",[24,410,415],{"alt":411,"height":412,"src":413,"width":414},"A rendered report card PDF for Fatima Abdullahi of JSS 1A, First Term 2026\u002F2027. Four of her six subjects are named in Arabic and two in English, and the Arabic names sit right-aligned in the same column as Computer Science and English Language, each row carrying the same total, grade and remark. Both remark panels below are written in Arabic and set right to left: the teacher's runs across two lines and contains the numeral 91 and the Latin words Computer Science inside the Arabic sentence, each placed in reading order rather than at the end of the line.",2339,"\u002Fblog\u002Fright-to-left-text\u002Freport-card.png",1656,[11,416,417],{},"It pairs with the Hijri calendar option, which lets a school read and enter dates in the Umm al-Qura\ncalendar, the Gregorian one, or both, without changing a single stored date. Both are the same idea:\na school should be able to run in the language and the calendar it actually uses, and neither should\nrequire a separate version of the product.",{"title":130,"searchDepth":131,"depth":131,"links":419},[420,421,422,423,424],{"id":333,"depth":134,"text":334},{"id":346,"depth":134,"text":347},{"id":374,"depth":134,"text":375},{"id":392,"depth":134,"text":393},{"id":404,"depth":134,"text":405},"Guides","A school asked why the Arabic on its report cards was gibberish. It was not gibberish, and that is what made it hard to spot. What it takes to print Arabic properly in a PDF.",{},"\u002Fblog\u002Fright-to-left-text",{"title":322,"description":426},"blog\u002Fright-to-left-text",[432,433,155],"report-cards","internationalisation","hhNFq4YguQCpT35AUSKtoYrKGXURJ6UNf3aOCq1DCXY",1787681163351]