{"id":25109908,"url":"https://github.com/fiveladdercon/mean-wringer","last_synced_at":"2025-04-02T09:25:38.194Z","repository":{"id":96150714,"uuid":"46527834","full_name":"fiveladdercon/mean-wringer","owner":"fiveladdercon","description":"An evaluation tool for assessing problem comprehension, coding correctness, eloquence and rigour.","archived":false,"fork":false,"pushed_at":"2015-11-20T14:32:21.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-08T00:32:45.112Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fiveladdercon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-19T23:59:19.000Z","updated_at":"2017-09-05T00:33:52.000Z","dependencies_parsed_at":"2023-03-13T16:37:00.655Z","dependency_job_id":null,"html_url":"https://github.com/fiveladdercon/mean-wringer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiveladdercon%2Fmean-wringer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiveladdercon%2Fmean-wringer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiveladdercon%2Fmean-wringer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiveladdercon%2Fmean-wringer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fiveladdercon","download_url":"https://codeload.github.com/fiveladdercon/mean-wringer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246786626,"owners_count":20833725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-08T00:32:51.450Z","updated_at":"2025-04-02T09:25:38.141Z","avatar_url":"https://github.com/fiveladdercon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"The MEAN Wringer\n================\n\nThis package is intented as an evaluation tool.  It is used to evaluate \neverything from problem comprehension to coding skills and style using \nreal-world requirements to be implemented using the MEAN stack (though \nMongoDB is not used in this exercise).  In essence, the intent is to\n__put you through the wringer__; hence the name of the project.\n\nInstructions\n------------\n\n1. Install Git \u0026 Node.\n2. Clone this repository: `\u003e git clone https://github.com/fiveladdercon/mean-wringer.git`\n3. NPM install: `\u003e npm install`\n4. Start the server: `\u003e node server.js`\n5. Direct your browser to `localhost:3000`\n6. Read the rest of this README.md and complete the tasks.\n7. Submit a \u003cyourname\u003e pull request when finished.\n\n\nClient Side Requirements\n------------------------\n\nThe application manages a collection of objects.  There are three classes\nof object (Student, Course, Classroom), each with several instances.\n\nThe presentation and interaction with each object is made consistent through\nthe use of the mwObject transcluding AngularJS directive, which gives all objects\nthe same general look-and-feel.\n\n\n__[R1]__ \nBy default all objects need to be read-only.  An edit button is provided to \nunlock the objects, and when clicked, means the properties can be modified.  The \nedit button is replaced by a save button, that when clicked returns the objects \nback to a read-only state (and pushes changes to the server).\n\nThe Edit \u0026 Save buttons just toggle an editing boolean in the mwObject scope.\nWhat's missing is the mechanism to disable/highlight form inputs.  This can\neasily be done with the ng-class \u0026 ng-disabled Angular directives, but the\nsyntax is repetitive and error prone.  Instead, this functionality is to\nbe encapsulated in the mwLocking directive, which can be added to input tags:\n\n    \u003cinput mw-locking ng-model='object.property'/\u003e\n\n\n__[R2]__\nStudents and Courses need to support one or more __attachments__, which are \narbitrary files related to these objects that have been uploaded to the server.\n(e.g. course materials can be attached to any given course).  Note that\nClassroom objects do not support attachments.\n\nTo keep attachment management consistent, each object that supports attachments\nis to instantiate an mwAttachements directive.  The directive needs to:\n\n* Fetch \u0026 list the attachments related to the object, providing:\n  - a way to delete the attachment (while editing),\n  - a way to update the attachment file name (while editing)\n  - a way to open the attachment (while not editing), and\n  - a way to download the attachment (while not editing)\n\n* Provide an Add button (while editing) that opens a file browser and allows \n  the upload of one or more files.  This button is to be styled similar to the \n  Edit/Save buttons, and thus can not be a displayed `\u003cinput type='file'/\u003e` tag.\n\nUploads are to be POSTED immediately on Add (and the displayed list updated\non upload complete), while file name updates are to be PUT only when the \nobject is saved.  Upload progress should be presented as a temporary placeholder(s) \nfor the uploaded file(s) until they have been successfully uploaded.\n\n\n__[R3]__\nIn addition to the Add button for adding attachments, attachments may be simply\nbe dropped anywhere on the object (while editing).  This capability is enabled \nvia the attachable boolean in each object and requires modifying the mwObject\ndirective to support the HTML 5 drag-n-drop capability and coordinate the \nupload in the transcluded mwAttachables directive.\n\n\nServer Side Requirements\n------------------------\n\nThe server actually serves two things: a JSON REST API for managing server\nresources and HTML/AngularJS web-client for initiating JSON requests and \ndisplaying the responses.\n\n__[R4]__\nServer side storage of attachments is to be abstracted from the client.\nALL attachment files are to be stored in a single flat folder and the\nmeta-data is to be stored in a database.  For example, a professor \nattaches a \"syllabus.pdf\" file to a Course object, the server will\n\n* store this as:\n\n    `uploads/S0MeRaNDoMsTriNG0fCHaRacTERs.pdf`\n\n* store a meta-data record of:\n\n    `{ \n    \tid      : 10, \n      label   : 'syllabus.pdf'\n    \tobject  : 'Course/1', \n    \tfile    : 'S0MeRaNDoMsTriNG0fCHaRacTERs.pdf'\n    }`\n\n* and present only the following meta-data to the client:\n\n    `{ \n    \tid         : 10, \n    \tobjectId   : 1, \n    \tobjectType : 'Course', \n      label      : 'syllabus.pdf'\n    }`\n\n\n__[R5]__\nAttachment support must provided through the following JSON REST API:\n\n#### GET /api/:type/:i/attachments  ####\n\nReturn a list of attachments for instance :i of object :type:\n\n    [ \n      {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'}, \n      {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'},\n      ... \n    ]\n\n#### POST /api/attachments ####\n\nUpload one or more files for instance :i of object :type.  Note that this is a \nmulti-part post, where :i \u0026 :type need to be posted in addition to the file data.\nWhen the upload completes, either one attachment or a list of attachments are\nreturned (depending on wheter one or many attachments where POSTed):\n\n    [ \n      {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'}, \n      {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'},\n      ... \n    ]\n\n -OR-\n\n    {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'}\n\n#### PUT /api/attachment/:x ####\n\nUpdate the label of the attachment.  THIS IS TO ONLY CHANGE THE LABEL PROPERTY,\nNOT THE FILE ON THE SERVER (SEE REQUIREMENT 4 ABOVE).  The updated object is\nto be returned in the response:\n\n    {id:integer, objectId:\u003c:i\u003e, objectType:\u003c:type\u003e, label:'string'}\n\n#### GET /api/attachment/:x ####\n\nResponds with attachment :x (for instance :i of object :type, which is implicit in :x).\nIf the query string includes ?download, forces a download in the client.\n\n#### DELETE /api/attachment/:x ####\n\nDeletes attachment :x, including the actual file.\n\n\nTasks\n-----\n\n__[T1]__ (AngularJS) Implement the mwLocking directive in client.js __[R1]__.\n\n__[T2]__ (AngularJS) Implement the mwAttachments directive in client.js __[R2]__.\n\n__[T3]__ (AngularJS) Add Attachment drag-n-drop support to the mwObject directive in client.js __[R3]__.\n\n__[T4]__ (Node.js) Implement the create/read/update/delete/find methods in memory.js.\n\n__[T5]__ (Node.js) Extend the Memory class in jsonfile.js to persist the struct list in a .json file __[R4]__.\n\n__[T6]__ (Express) Implement the Attachments JSON API in server.js __[R5]__.\n\n\nEvaluation Criteria\n-------------------\n\nIn evaluating your submission, I expect __code correctness__ - which is to say that it \ndoes what it is required to do; and to do so out-of-the-box (following the first 5 steps\nof the instructions above).  Beyond that I expect __coding eloquence__, which I mean to \nbe an appropriate balancing of simplicity, efficiency, organization, readability and \nunderstandability against the complexity of funcional requirements.  And finally, I \nexpect __coding rigour__, which means that your code is production worthy - i.e. \ncommented, linted and regression tested.\n\n\nPackage Files\n-------------\n\n### Server Side Files ###\n\n__server.js__    \n\u003e An Express application that serves an HTML client and a JSON REST API \n\u003e or managing attachments.\n\n__memory.js__ \n\u003e A storage model that stores a list of structs with a common schema in memory, \n\u003e giving each struct a unique id.\n\n__jsonfile.js__\n\u003e A storage model that stores a list of structs with a common schema in a file \n\u003e in JSON format, giving each struct a unique id.\n\n### Client Side Files ###\n\n__client.js__\n\u003e The Angular directives required for the HTML client.\n\n__client.html__ \n\u003e The HTML client that presents attachable and non-attachable objects in a list.\n\n__object.html__\n\u003e An HTML template for displaying an object as a component with it's own controls.\n\n### Project Files ###\n\n__README.md__  \n\u003e This file.\n\n__package.json__\n\u003e The npm package file listing dependencies (express, body-parser, multer).\n\n__.gitignore__\n\u003e Disables tracking of node_modules in git.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiveladdercon%2Fmean-wringer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffiveladdercon%2Fmean-wringer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiveladdercon%2Fmean-wringer/lists"}