lamenezes / status-map Goto Github PK
View Code? Open in Web Editor NEWStatus map and transitions validation made easy
License: MIT License
Status map and transitions validation made easy
License: MIT License
so we won't forget to create and push release tags
e.g. given the following status map
on the following status history:
if someone tries to change the status to published
how do we know if it is past or future? we don't
that happens because of cycles in the map. when there's on of those we can't predict with 100% certainty if the status is past or future.
therefore I propose we disable future/past checks on maps with cycles, i.e. on status validation alwas raise only InvalidTransition
instead of RepeatedTransition
etc.
if there's no cycle present we can assume if it's past or future and raise the related errors when performing status transition validation.
and perform flake8, code formatting (using black) etc. directly on CI
Does the networkx ancestor/descendant algorithms repeat the calculations for repeated from and to status? Does it make sense to cache those values for future use to avoid needless computations?
not sure how this would look, but I can see people that already use enums for "status handling" (or similar stuff) wanting the features status map provides.
we might tackle this with a enum-like interface:
from status_map.enum import StatusEnum # this should be compatible with std lib's enum.Enum
class TaskEnum(StatusEnum):
TODO = 0 # there might be a better way to do this in the std lib
DOING = 1
DONE = 2
The issue here is: how do we handle the transitions having an interface like that?
We might appeal to a django-like Meta class (I'm not really a fan of it though):
class TaskEnum(StatusEnum):
TODO = 0
DOING = 1
DONE = 2
class Meta:
transitions = {'TODO': ['DOING'], 'DOING': ['TODO', 'DONE'], 'DONE': []}
Another possibility is to bet on a more of a "freestyle" method:
class TaskEnum(StatusEnum):
TODO = 0, 'task waiting for someone work on it', ['DOING']
DOING = 1, 'task in progess', ['TODO', 'DONE"]
DONE = 2, 'task ready!', [] # adding the possibility to the user describe what each status means
It's not very intuitive but at the same time not complicated. With this approach I think we save a lot of code and can even add some meaning to all this. And it's not too difficult to implement if we use the aenum [1] lib.
Those two were the best alternatives I could think of, but there might be better ideas.
Status class next
and previous
attributes are set
objects, when StatusMap
process these attributes the order are ignored and this operation can result in unexpected behavior:
StatusMap({
"": ("created", "sent"),
"created": ("sent", "sent_error"),
"sent": ("published", "rejected"),
"sent_error": ("created",),
"rejected": ("sent",),
"published": ("rejected",),
})
This example has some status linked one with other, ex: created -> sent_error -> created
, sent -> rejected -> sent
, this kind of relationship can cause unexpected behaviour if order of the values are ignored, resulting is a StatusMap
with previous
and next
wrong relationship.
it would be nice to have a StatusMap.draw()
method that gave us a way to view the status map. it could start with ascii art, but we also could add support to pdf etc.
it would be great if when working with django we could do something like:
from status_map.django import StatusField
class Task(Model):
status = StatusField(status_map={'todo': ['doing'], 'doing': ['todo', 'done'], 'done': []})
title = CharField(...)
>>> task = Task(title='implement django support on status-map') # defaults to the first status passed (todo)
>>> task.status = 'done'
>>> task.save()
status_map.exceptions.TransitionNotFoundError: transition from todo to done not found
instead of something like:
from status_map import StatusMap
TASK_STATUS_MAP = StatusMap({'todo': ['doing'], 'doing': ['todo', 'done'], 'done': []})
class Task(Model):
status = ChoiceField(choices=TASK_STATUS_MAP._map.keys(), default='todo')
# not using validators because I'm pretty sure we can't acess the current status on the db
def save(self, *args, **kwargs):
task = Task.objects.get(pk=self.pk)
if task.status != self.status:
TASK_STATUS_MAP.validate_transition(task.status, self.status)
return super().save(*args, **kwargs)
minimal instructions on how to use and how to contribute
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.