// Public sample credentials for this browser-local prototype only.exportconstdemoPasswords={user:'team-demo',administrator:'admin-demo'};exportconstdefaultTeamAccess={userHash:'5ad5c1934a4602677ed173d3bf0d69aab489aba11309b165f0b68725220fcf47',administratorHash:'198352b6a8078a827be267c847d39506629d3af446a3cc0bce670dd3a6b5d753',};exportasyncfunctionhashPassword(password){constbytes=awaitcrypto.subtle.digest('SHA-256',newTextEncoder().encode(password));return[...newUint8Array(bytes)].map(byte=>byte.toString(16).padStart(2,'0')).join('');}exportasyncfunctionauthenticateTeam(state,team,password){if (!state.teams.includes(team)||!password)thrownewError('Choose a team and enter the system password.');constaccess=state.teamAccess[team];constdigest=awaithashPassword(password);constrole=digest===access?.administratorHash?'administrator':digest===access?.userHash?'user':'';if (!role)thrownewError('The password does not match the selected team.');return{team,role,name:`${team}${role==='administrator'?'Administrator':'User'}`,authenticated:true};}exportfunctionnormalizeAccessModel(state){state.templates.forEach(template=>{template.name=template.name.replace(/CCIL/g,'Testcraft');});state.documents.filter(doc=>doc.synthetic).forEach(doc=>{doc.excerpt=doc.excerpt?.replace(/CCIL/g,'Testcraft');});state.teamAccess||={};for (constteamofstate.teams)state.teamAccess[team]||={...defaultTeamAccess};constidentity=name=>typeofname==='string'?name.replace(/ (Normal User|Contributor|Reviewer|Baseline Approver|Developer|Business User|BA)$/,' User'):name;state.session.name=`${state.session.team}${state.session.role==='administrator'?'Administrator':'User'}`;state.questions.forEach(q=>{q.author=identity(q.author);q.resolvedBy=identity(q.resolvedBy);q.validatedBy=identity(q.validatedBy);});state.audit.forEach(a=>{a.actor=identity(a.actor);a.action=a.action.replace(/ as (Normal User|Contributor|Reviewer|Baseline Approver|Developer|Business User|BA)$/,' as User');});Object.values(state.threads).forEach(thread=>thread.messages?.forEach(m=>{m.actor=identity(m.actor);}));state.candidates.forEach(c=>c.decisions?.forEach(d=>{d.actor=identity(d.actor);}));if (state.accessModelVersion===1)returnstate;state.session.role=state.session.role==='administrator'?'administrator':'user';state.session.authenticated=false;state.workspaces.forEach(w=>{w.visibility='team';w.members=[w.team];});state.baselines.forEach(b=>{if (b.status==='Approved'&&!b.parentId)b.status='Active';});state.questions.forEach(q=>{if (q.status==='validated'||(q.status==='submitted'&&q.answer&&q.sourceReference&&(q.answerSourceId||q.sourceId)))q.status='resolved';elseif (q.status==='submitted')q.status='open';q.author=identity(q.author);q.resolvedBy=identity(q.validatedBy||q.author);});state.templates.forEach(t=>{t.fields=t.fields.map(f=>f==='Reviewer status'?'Review status':f);});state.suites.forEach(s=>{if (s.templateSnapshot)s.templateSnapshot.fields=s.templateSnapshot.fields.map(f=>f==='Reviewer status'?'Review status':f);});state.accessModelVersion=1;returnstate;}exportfunctiondocumentInputIssues(documents){returndocuments.length?[]:['Upload at least one Business, Technical, or Functional / Bug Information document.'];}exportfunctionaddTeam(state,name,userHash,administratorHash){if (!state.session.authenticated||state.session.role!=='administrator')thrownewError('Only an Administrator can add a team.');if (!name||state.teams.some(team=>team.toLowerCase()===name.toLowerCase()))thrownewError('Enter a unique team name.');if (![userHash,administratorHash].every(hash=>/^[a-f0-9]{64}$/.test(hash))||userHash===administratorHash)thrownewError('Provide different User and Administrator system passwords.');state.teams.push(name);state.teamAccess[name]={userHash,administratorHash};}exportfunctionbaselineInputIssues(state,name,documents){return[...(!name.trim()?['Enter a System Baseline name.']:[]),...(state.baselines.some(b=>b.team===state.session.team&&b.status!=='Rejected'&&b.ref===name.trim())?['This System Baseline name already exists.']:[]),...documentInputIssues(documents)];}exportfunctionsaveClarification(state,workspace,questionId,answer,sourceId,reference,documents){constq=state.questions.find(q=>q.id===questionId&&q.workspaceId===workspace.id&&q.version===workspace.version);if (!q||!answer.trim()||!reference.trim()||!documents.some(d=>d.id===sourceId&&['Ready','Reviewed locally'].includes(d.status)))thrownewError('Provide an answer, an accessible source, and its revision / location.');Object.assign(q,{answer:answer.trim(),answerSourceId:sourceId,sourceReference:reference.trim(),status:'resolved',author:state.session.name,resolvedBy:state.session.name,answeredAt:newDate().toISOString()});}
Top comments (0)
Subscribe
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (0)